Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 28.11.2024, 11:35
infopol infopol сейчас на форуме
Прохожий
 
Регистрация: 03.06.2021
Сообщения: 40
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Передача массива в собственную ComDll

Здравстуйте!Дело в том что нельзя выбрать параметр как массив,как и создать свой тип данных например TArrayString. Но пришла идея передать массив как OleObject

Код:
obj:=CreateOleObject("System.Collections.ArrayList")  
в него obj.Clear ; 
 obj.Add(<строка>)
Админ: Пользуемся тегами при оформлении кода!

И передаем в функцию : MyArrayFunc(obj:OleVariant):Variant;
И также можем из функции Dll передать данные обратно в виде OleObject

Последний раз редактировалось Admin, 28.11.2024 в 11:49.
Ответить с цитированием
  #2  
Старый 29.11.2024, 04:28
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,063
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

вот что нагенерил ИИ:
Код:
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  
Старый 29.11.2024, 16:15
infopol infopol сейчас на форуме
Прохожий
 
Регистрация: 03.06.2021
Сообщения: 40
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Дело в том,что я делаю собственные ComDll для бухпрограммы...

Приветствую! Я работаю с программой "Инфо-Предприятие",не все там есть,но при небольшом умении программирования в Delphi( CBuilder я не знаю) можно дополнить и причем значительно функционал.
Вот и придумал использовать данные Объект как параметр.
Ну если можно создать свой OleObject например ArreyObj с методами Add,Count,Item и т.д...было бы неплохо получить исходный код такого объекта и внедрить ее в свою библу.
Ответить с цитированием
  #4  
Старый 30.11.2024, 09:18
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,063
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А тебе и не надо создавать именно COM-объект для этого.
Можешь создать простой класс с твоими методами Add/Count/Items и т.д. И еще один метод, например, toOleArray, который и сформирует тебе OleVariant с упакованным внутрь массивом.
Более того, если верися Дельфи не очень старая, то можно сделать шаблонный класс. Тогда можно будет упаковывать в такие массивы любые данные.
Кстати, таким образом можно упаковывать и COM-объекты для передачи.
Ответить с цитированием
  #5  
Старый 30.11.2024, 10:14
infopol infopol сейчас на форуме
Прохожий
 
Регистрация: 03.06.2021
Сообщения: 40
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Сделал такой пример

Цитата:
Сообщение от lmikle
вот что нагенерил ИИ:
Код:
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
Код:
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.
Задача создать свой OleObject для работы с массивами.Просто у меня мало знаний.Я занимаюсь автоматизацией бухучета.А Delphi это как помощь для расширения функционала

Последний раз редактировалось infopol, 30.11.2024 в 10:25.
Ответить с цитированием
  #6  
Старый 02.12.2024, 08:11
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,063
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Непонятно что конкретно тебе надо сделать. Точнее в чем проблема.
Вот более полный пример:

Форма:
Код:
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  
Старый 02.12.2024, 10:40
infopol infopol сейчас на форуме
Прохожий
 
Регистрация: 03.06.2021
Сообщения: 40
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Описание задачи

Спасибо за ответ.Вот описание задачи по созданию 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]))
П.П. Заранее благодарен. CreateOleObject("System.Collections.ArrayList") не на всех компутерах работает и не знаю как ее зарегистрировать.

Последний раз редактировалось infopol, 02.12.2024 в 11:06.
Ответить с цитированием
  #8  
Старый 02.12.2024, 19:58
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,063
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ой, чёт мне кажется, что это какое-то учебное задание.
А мы помним, что COM - это stateless модель? Это так, на всякий случай.

По теме.
Тогда тебе надо создавать ActiveX Library, внутри нее COM object и уже там, в библиотеке типов создавать свойства и методы, а потом реализовывать это в Co-классе. Просто по пути не забываем, что нам надо использовать COM-safe типы данных (например, обычная паскалевская строка, которая String, не является таким типом).
Тут я бы посоветовал найти видел по тому как работать с редактором библиотеки типов в Дельфи. Это именно тот случай, когда лучше один раз увидеть... Ну а внутренняя реализация всех этих методов довольно стандартна.
Ответить с цитированием
  #9  
Старый Сегодня, 09:29
infopol infopol сейчас на форуме
Прохожий
 
Регистрация: 03.06.2021
Сообщения: 40
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Вот так должен использоваться объект из DLL

Цитата:
Сообщение от lmikle
Ой, чёт мне кажется, что это какое-то учебное задание.
А мы помним, что COM - это stateless модель? Это так, на всякий случай.

По теме.
Тогда тебе надо создавать ActiveX Library, внутри нее COM object и уже там, в библиотеке типов создавать свойства и методы, а потом реализовывать это в Co-классе. Просто по пути не забываем, что нам надо использовать COM-safe типы данных (например, обычная паскалевская строка, которая String, не является таким типом).
Тут я бы посоветовал найти видел по тому как работать с редактором библиотеки типов в Дельфи. Это именно тот случай, когда лучше один раз увидеть... Ну а внутренняя реализация всех этих методов довольно стандартна.
Это производственное.
Должно быть по примеру
Код:
  ЕСЛИ ЕСТЬ_ОБЪЕКТ("System.Collections.ArrayList") ТО
arr=СОЗДАТЬ_ОБЪЕКТ!("System.Collections.ArrayList")
arr.Clear
arr.Add("Привет")
arr.Add("Всем")
arr.Add("от меня")
//arr.Reverse()
//arr.Sort()  
// arr.Remove("Всем")
// arr.RemoveAt(2)
//N= arr.Count   
пар!""=""         
ОБНУЛИТЬ(пар)     
ЦИКЛ ДЛЯ(а=0,arr.Count-1)
//ОТЛАДКА(arr.Item[а])
пар!а  = arr.Item[а]
КОНЕЦ_ЦИКЛА         
  КОНЕЦ_ЕСЛИ       
только вместо "System.Collections.ArrayList" мой OleObject "ArrayCom"
переменная добавляемая в массив объекта ArrayCom может быть Число,Строка,Дата,Логика,Время.
П.П. Заранее благодарен за помощь.

Последний раз редактировалось infopol, Сегодня в 09:46.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:17.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter