Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.08.03;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.009 c
15-1213716332
Dmitry S
2008-06-17 19:25
2008.08.03
Перестановки


2-1214983297
Олег-5
2008-07-02 11:21
2008.08.03
TListBox + пустое есто


2-1215282066
observateur
2008-07-05 22:21
2008.08.03
ClientDataSet


2-1214779198
Андрей_1
2008-06-30 02:39
2008.08.03
Exel в Paradox


6-1191397323
Gydvin
2007-10-03 11:42
2008.08.03
Узнать IP





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский