Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.08.03;
Скачать: CL | DM;

Вниз

Передача массивов через СОМ.   Найти похожие ветки 

 
Darvin ©   (2008-07-02 10:29) [0]

Здравствуйте!
Программа на Delphi должна использовать com сервер, написанный на C#. Все бы ничего, но параметрами методов интерфейса должны быть динамические массивы или любой другой тип для передачи относительно больших объемов данных (несколько килобайт). Взаимодействие с простым типом данных я отработал. В сервере на C# пишу следующее:

private int[] arr1;
public void SetData(object data)
{
 arr1 = (int[])data;
}


Как это можно интерпретировать на Delphi?
Я делал следующим образом:

 ITestIface1= interface
   ["{CDE93811-24B5-4920-A543-8790EE403F31}"]
   procedure Method1 ( out A : Integer );     stdcall;
   procedure Method2 ( A : Integer; out B : Integer ); stdcall;
   procedure SetData ( Data : OleVariant ); stdcall;
   function  GetData : OleVariant; stdcall;
 end;  // of ITestIface

var
 FTest1 : ITestIface1;

...

procedure TForm4.FormCreate(Sender: TObject);
begin
 try
   // Создаем COM-объект и запрашиваем у него интерфейс
   FTest1 := CreateComObject(CLASS_Test1Auto) as ITestIface1;
 except
   on E : EOleSysError do begin
     FTest1 := nil;
     edData.Text := "Ошибка";
   end;
 end;
end;

procedure TForm4.Button1Click(Sender: TObject);
var
 Data : OleVariant;
 I    : Integer;
begin
 Data := VarArrayCreate ( [0, 9], varInteger );
 Data := FTest1.GetData;
 edData.Text := "";
 for I:=0 to 9 do
   edData.Text := edData.Text + IntToStr ( Data[I] );
end;


При выполнении строчки Data := FTest1.GetData; вылетает ошибка.


 
Ega23 ©   (2008-07-02 10:33) [1]

Buffer : Pointer
BuffLength : DWORD

?


 
Василий Жогарев ©   (2008-07-02 10:35) [2]


> private int[] arr1;
> public void SetData(object data)
> {
>  arr1 = (int[])data;
> }

Покажи полный скелет интерфейса написанный на C#.


 
Darvin ©   (2008-07-02 10:38) [3]

Собственно, вот:
namespace LibraryTest
{
   [GuidAttribute("CDE93811-24B5-4920-A543-8790EE403F31")]
   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(true)]
   public interface IMyInteface1
   {
       void Method1(out int a);
       void Method2(/*[in]*/ int a, out int b);
       void SetData(object data);
       object GetData();
   }

   [Guid("43668C3A-4C10-4381-9959-287FE971E7C9")]
   [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
   public class Class1 : IMyInteface1
   {
       private int num = 5;
       private int[] arr = {0,1,2,3,4,5,6,7,8,9};
       private int[] arr1;

       public void Method1(out int a)
       {
           a = num;
       }
       public void Method2(/*[in]*/ int a, out int b)
       {
           b = a * a;
       }
       public void SetData(object data)
       {
           arr1 = (int[])data;
       }
       public object GetData()
       {
           return arr;
       }
   }
}


 
umbra ©   (2008-07-02 10:41) [4]


> При выполнении строчки Data := FTest1.GetData; вылетает
> ошибка.

какая?


 
Darvin ©   (2008-07-02 10:41) [5]

> Ega23 ©
А как pointer передать через com? В стандартных типах его нет...


 
Darvin ©   (2008-07-02 10:43) [6]

>umbra ©
не пишет. Project1 обнаружена ошибка. Приложенние будет закрыто. При трассировке останавливается, вызывая окно CPU


 
Ega23 ©   (2008-07-02 10:45) [7]

PChar?


 
Василий Жогарев ©   (2008-07-02 10:45) [8]

Я так думаю ошибка у тебя получается вот тут Data := VarArrayCreate ( [0, 9], varInteger );. Хотя могу и ошибаться.


 
Darvin ©   (2008-07-02 10:48) [9]

> Василий Жогарев ©
Нет, эта строка проходит нормально. Я писал сервер на Delphi, там без этой строки не работает


 
Сергей М. ©   (2008-07-02 10:48) [10]

Подозреваю, что соглашение о вызове должно быть safecall


 
Darvin ©   (2008-07-02 10:49) [11]

>Ega23 © PChar?
А если внутри нулевые элементы массива?


 
Darvin ©   (2008-07-02 10:49) [12]

>Сергей М. ©
надо попробовать. для простых типов работает stdcall


 
umbra ©   (2008-07-02 11:03) [13]

для передачи произвольных данных подходит тип bstr (он же WideString :))
Но распаковку и упаковку данных надо будет проводить вручную.


 
Darvin ©   (2008-07-02 11:16) [14]

Попробовал создать unit из tlb файла, параметры массивы типа PSafeArray


 
tesseract ©   (2008-07-02 11:20) [15]


> для передачи произвольных данных подходит тип bstr (он же
> WideString :))


Для передачи массива через COM идеально подходит SafeArray. Который delphi в принципе может как VariantAray трактовать, но я вручную, нужную мне часть переписал.


> А как pointer передать через com? В стандартных типах его
> нет...


Странно по TCP-IP тоже не передаёться. Смотри  iStream + CreateStreamOnHGlobal лучше для передачи.  Можно просто через глобальную память, но не уверен, что это правильный шаг.


 
Darvin ©   (2008-07-02 11:29) [16]

>tesseract ©
Пример работы с SafeArray можешь кинуть?


 
Василий Жогарев ©   (2008-07-02 11:35) [17]


> Пример работы с SafeArray можешь кинуть?

http://delphimaster.net/view/10-1209549911/


 
Сергей М. ©   (2008-07-02 11:45) [18]


> Darvin ©   (02.07.08 10:49) [12]
>
> >Сергей М. ©
> для простых типов работает stdcall


Разберись для начала, в чем принципиальное отличие этих соглашений


 
DiamondShark ©   (2008-07-02 19:35) [19]


> Я делал следующим образом:
>
>  ITestIface1= interface
>    ["{CDE93811-24B5-4920-A543-8790EE403F31}"]
>    procedure Method1 ( out A : Integer );     stdcall;
>    procedure Method2 ( A : Integer; out B : Integer ); stdcall;
>
>    procedure SetData ( Data : OleVariant ); stdcall;
>    function  GetData : OleVariant; stdcall;
>  end;  // of ITestIface

Это какой-то неиллюзорный трандец.

либо
function  GetData : OleVariant; safecall;
либо
function GetData(out RetVal: OleVariant): HRESULT; stdcall;


> надо попробовать. для простых типов работает stdcall


Вы что, эти слова как заклинания используете, не вникая в смысл?



Страницы: 1 вся ветка

Текущий архив: 2008.08.03;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.024 c
2-1214919159
Фленов
2008-07-01 17:32
2008.08.03
Как засунуть файл в *.exe ?


2-1214643313
Дядя Педро
2008-06-28 12:55
2008.08.03
WinAMP


15-1213518786
Галинка
2008-06-15 12:33
2008.08.03
Canon Pixma iP2500


15-1213603995
TUser
2008-06-16 12:13
2008.08.03
Что делать с Raid-дисками?


15-1213651482
k2_
2008-06-17 01:24
2008.08.03
Симпатишный дизайн, полюбуйтесь.