Текущий архив: 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.52 MB
Время: 0.006 c