![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Здравстуйте!Дело в том что нельзя выбрать параметр как массив,как и создать свой тип данных например TArrayString. Но пришла идея передать массив как OleObject
Код:
obj:=CreateOleObject("System.Collections.ArrayList")
в него obj.Clear ;
obj.Add(<строка>)И передаем в функцию : MyArrayFunc(obj:OleVariant):Variant; И также можем из функции Dll передать данные обратно в виде OleObject Последний раз редактировалось Admin, 28.11.2024 в 11:49. |
|
#2
|
|||
|
|||
|
вот что нагенерил ИИ:
Код:
type
IMyComInterface = interface(IDispatch)
['{00000000-0000-0000-0000-000000000000}']
procedure ProcessArray(Values: OleVariant); safecall;
end;Код:
procedure TMyComObject.ProcessArray(Values: OleVariant);
var
i: Integer;
begin
if VarIsArray(Values) then
begin
for i := VarArrayLowBound(Values, 1) to VarArrayHighBound(Values, 1) do
begin
// Process each element in the array
ShowMessage(IntToStr(Values[i]));
end;
end;
end;Вызов: Код:
var ComObj: IMyComInterface; Values: OleVariant; begin ComObj := CreateComObject(CLASS_MyComObject) as IMyComInterface; Values := VarArrayCreate([0, 2], varInteger); Values[0] := 10; Values[1] := 20; Values[2] := 30; ComObj.ProcessArray(Values); end; Тут передача интов в примере, поменять на varString, а исходный массив - простой динамический массив, только надо посмортеть, если не ошибаюсь, то лучше использовать Array Of WideString Последний раз редактировалось lmikle, 29.11.2024 в 04:31. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
infopol (29.11.2024)
| ||
|
#3
|
|||
|
|||
|
Приветствую! Я работаю с программой "Инфо-Предприятие",не все там есть,но при небольшом умении программирования в Delphi( CBuilder я не знаю) можно дополнить и причем значительно функционал.
Вот и придумал использовать данные Объект как параметр. Ну если можно создать свой OleObject например ArreyObj с методами Add,Count,Item и т.д...было бы неплохо получить исходный код такого объекта и внедрить ее в свою библу. |
|
#4
|
|||
|
|||
|
А тебе и не надо создавать именно COM-объект для этого.
Можешь создать простой класс с твоими методами Add/Count/Items и т.д. И еще один метод, например, toOleArray, который и сформирует тебе OleVariant с упакованным внутрь массивом. Более того, если верися Дельфи не очень старая, то можно сделать шаблонный класс. Тогда можно будет упаковывать в такие массивы любые данные. Кстати, таким образом можно упаковывать и COM-объекты для передачи. |
|
#5
|
|||
|
|||
|
Цитата:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,ComObj,
OleConst,OleCtrls,ShlObj, ComServ,Types,
Dialogs, StdCtrls;
type
IMyComInterface = interface ['{00000000-0000-0000-C000-000000000000}']//{00CA209B-5FB2-4EDA-952C-4C286F59EF9B}']
// function GetNumber : Integer;
end;
TMyComObject = class (TInterfacedObject,IMyComInterface)
private
procedure ProcessArray(Values: OleVariant);
public
end;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
//const
//CLASS_MyComObject: TGUID = '{00000000-0000-0000-C000-000000000000}';
{$R *.dfm}
procedure TMyComObject.ProcessArray(Values: OleVariant);
var
i: Integer;
begin
form1.Memo1.Clear;
form1.Memo1.Lines.Add('Òåñò ïðîöåäóðû ProcessArray(Values)');
if VarIsArray(Values) then
begin
form1.Memo1.Lines.Add('Ðàçìåð '+IntToStr(VarArrayHighBound(Values, 1)+1 ));
for i := VarArrayLowBound(Values, 1) to VarArrayHighBound(Values, 1) do
begin
// Process each element in the array
form1.Memo1.Lines.Add(IntToStr(Values[i]));
// ShowMessage(IntToStr(Values[i]));
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ComObj: TMyComObject;//IMyComInterface;
Values: OleVariant;
begin
ComObj:=TMyComObject.Create();
//ComObj := //CreateComObject(CLASS_MyComObject) as IMyComInterface;
Values := VarArrayCreate([0, 4], varInteger);
Values[0] := 10;
Values[1] := 20;
Values[2] := 30;
Values[3] := 40;
Values[4] := 50;
ComObj.ProcessArray(Values);
ComObj.Destroy;
end;
initialization
end.Последний раз редактировалось infopol, 30.11.2024 в 10:25. |
|
#6
|
|||
|
|||
|
Непонятно что конкретно тебе надо сделать. Точнее в чем проблема.
Вот более полный пример: Форма: Код:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Unit2, Unit3, Vcl.StdCtrls;
type
TForm1 = class(TForm)
btAddStr1: TButton;
btAddStr2: TButton;
btAddStr3: TButton;
btCall: TButton;
procedure btAddStr1Click(Sender: TObject);
procedure btAddStr2Click(Sender: TObject);
procedure btAddStr3Click(Sender: TObject);
procedure btCallClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
Buf : TParamsColleator;
procedure AddStrToBuf(S : String);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.AddStrToBuf(S: String);
begin
if Not Assigned(Buf) then Buf := TParamsColleator.Create;
Buf.Add(S);
end;
procedure TForm1.btAddStr1Click(Sender: TObject);
begin
AddStrToBuf('Str1');
end;
procedure TForm1.btAddStr2Click(Sender: TObject);
begin
AddStrToBuf('Str2');
end;
procedure TForm1.btAddStr3Click(Sender: TObject);
begin
AddStrToBuf('Str3');
end;
procedure TForm1.btCallClick(Sender: TObject);
var
Intf : IComDemoInterface;
params : OleVariant;
begin
If Not Assigned(Buf) Then raise Exception.Create('Buf is empty. Add values first.');
Intf := TComDemoImpl.Create;
Try
params := Buf.GetParamsArray;
Intf.ProcessArray(params);
Finally
Intf := Nil;
End;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Buf := Nil;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
If Assigned(Buf) Then FreeAndNil(Buf);
end;
end.Интерфейс с имплементацией: Код:
unit Unit2;
interface
type
IComDemoInterface = interface(IUnknown)
['{00000000-0000-ABCD-0000-000000000001}']
procedure ProcessArray(arr: OleVariant); safecall;
end;
TComDemoImpl = class(TInterfacedObject, IComDemoInterface)
procedure ProcessArray(arr: OleVariant); safecall;
end;
implementation
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants;
{ TComDemoImpl }
procedure TComDemoImpl.ProcessArray(arr: OleVariant);
var
I : Integer;
S : String;
begin
If Not VarIsArray(arr)
Then MessageBox(0,PChar('<no data>'),PChar('Received call, but param is not array:'),0)
Else
Begin
S := '';
For I := VarArrayLowBound(arr,1) To VarArrayHighBound(arr,1) Do
If VarIsStr(arr[i])
Then S := S + IntToStr(I) + ' : ' + arr[i] + #10#13
Else S:= S + IntToStr(I) + ' : <not string>' + #10#13;
MessageBox(0,PChar(S),PChar('Received call:'),0);
End;
end;
end.Аккумулятор для параметров (самый простейший, просто унаследовался от TStringList и добаил свою функцию): Код:
unit Unit3;
interface
uses
System.SysUtils, System.Variants, System.Classes;
type
TParamsColleator=class(TStringList)
public
function GetParamsArray : OleVariant;
end;
implementation
{ TParamsColleator }
function TParamsColleator.GetParamsArray: OleVariant;
var
I : Integer;
begin
Result := VarArrayCreate([0,Count-1],varOleStr);
For I := 0 To Count-1 Do
Result[i] := Strings[i];
end;
end. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
infopol (02.12.2024)
| ||
|
#7
|
|||
|
|||
|
Спасибо за ответ.Вот описание задачи по созданию ComDLL
1. Создать Com Dll 2. OleObject ArrayCom -OleVariant,можно TypeArray - тип данных в массиве. 3. Свойства Count -количество элементов в массиве 4. Методы Add - добавление в массив,Del (<N>) удаление элемента массива,Sort - сортировка массива,Revers- реверсирование,Clear - Очистка массива, Items[<N>] - получение значения массива Variant,OnArray - Array of variant. Код:
Arr:=CreateOleObject('ArrayCom')
Arr.Clear;
Arr.Add('Привет')
Arr.Add('это библиотека ')
Arr.Add('ArrayCom.Dll')
//или
{Arr.Add(100)
Arr.Add(245)
Arr.Add(1009)
}
for i=0 to Arr.Count do
ShowMessage(VarToString(Arr.Items[i]))Последний раз редактировалось infopol, 02.12.2024 в 11:06. |
|
#8
|
|||
|
|||
|
Ой, чёт мне кажется, что это какое-то учебное задание.
А мы помним, что COM - это stateless модель? Это так, на всякий случай. По теме. Тогда тебе надо создавать ActiveX Library, внутри нее COM object и уже там, в библиотеке типов создавать свойства и методы, а потом реализовывать это в Co-классе. Просто по пути не забываем, что нам надо использовать COM-safe типы данных (например, обычная паскалевская строка, которая String, не является таким типом). Тут я бы посоветовал найти видел по тому как работать с редактором библиотеки типов в Дельфи. Это именно тот случай, когда лучше один раз увидеть... Ну а внутренняя реализация всех этих методов довольно стандартна. |