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

Вниз

Передача массивом Ole объекту   Найти похожие ветки 

 
Koster   (2004-04-16 18:50) [0]

Краткая суть вопроса.

Как передавать массивы методам класса Ole объекта, интерфейс которого
находится в переменной типа Variant?

var
Interface: Variant;
a: array [1..10, 1..20] of Integer;
begin
Interface := CreateOleObject("ServerName.Class");
Interface.Test(a)
// - нужно передать такой массив "a" методу Test.
// Указанная строка не работает.
end;

Полное описание вопроса.

Есть DLLка, написаная на VB, содержащая в себе некий Ole объект
"ServerName.Class". (InProc Server)
Пусть в DLLке есть процедура (метод) Test, требующий в переводе на Delphiйский
язык, массив [1..10, 1..20] of Integer.
Как передавать массивы процедурам (методам класса) DLLки? причем доступные на
запись и на чтение.
Не проходит так:

var
Interface: Variant;
a: array [1..10, 1..20] of Integer;
begin
Interface := CreateOleObject("ServerName.Class");

Interface.Test(a)
end;

здесь ругается Delphi при компиляции:
"Type not allowed in Variant Dispatch call"

Если так:
var
Interface: Variant;
a: Variant;
begin
Interface := CreateOleObject("ServerName.Class");

a := varArrayCreate([1,10,1,20],varInteger);

Interface.Test(a);
end;

выдается ошибка времени выполнения "EOleException: Type mismatch".

Тогда пробую по другому. В Delphi делается Import Type Library, и выбирается
нужный объект, автоматом создается unit с описанием этой DLLки и всех
методов класса Class (т.е. создается описание класса TClass уже в Delphi).

Там процедура Test выглядит так:

procedure TClass.Test(var Array: PSafeArray);

Ее удается вызвать так:

var
Interface: TClass;

begin
Interface := TClass.Create(nil);

a := varArrayCreate([1,10,1,20],varInteger);
Class.Test(PSafeArray(TVarData(a).vArray));

end;

и все работает.
Но этот случай не годится тем, что при перекомпиляции DLLки требуется
переимпортировать модуль Type Library и каждый раз перекомпилировать всю
программу заново.Оно и понятно, ведь в unitе прописан не название класса
"ServerName.Class" а GUID, который меняется от версии к версии DLL.
DLLка меняется часто.

Пробую так:

type
IClass = interface(IDispatch)
 procedure Test(var Array: PSafeArray);
end;

var
Interface: IClass;

begin
Interface := CreateOleObject("ServerName.Class");

a := varArrayCreate([1,10,1,20],varInteger);
Class.Test(PSafeArray(TVarData(a).vArray));

end;

работает только, если выдрать описание интерфейса из модуля, сгенеренного
Delphi по команде Import Type Library.

При появлении новой DLLки вызовы идут, но как-то некорректно (лезут странные
ошибки, которых быть не должно, например выход за переделы диапазона).
И вызывается что-то не то.

Итак, как передать массивы в любую версию DLLки?

Прошу рабочий пример.


 
Asdor ©   (2004-04-20 19:00) [1]


var
  Interface: Variant;
  a:Variant
begin
  Interface := CreateOleObject("ServerName.Class");

  a := varArrayCreate([1,10,1,20],varInteger);

  Interface.Test(a);
end;


ИМХО должно работать.


 
Digitman ©   (2004-04-21 12:54) [2]


> требующий в переводе на Delphiйский
> язык, массив [1..10, 1..20] of Integer.


слишком фривольный перевод у тебя

OLE-объекты не знают никаких "Delphiйских" языков, зато знают строго определенный набор базовых типов, которыми могут быть параметры и результаты олей-вызовов ... в числе этих типов есть тип OleVariant, полная совместимость которого со стороны делфи и со стороны олей-объектов гарантирована ... более того - в Делфи этот тип был введен специально для поддержки средой и приложениями, созданными в ней, стандартных коммуникаций с олей-объектами

var
 Interface:  OleVariant;
 ParamArray: OleVariant
begin
 Interface := CreateOleObject("ServerName.Class");

 ParamArray := VarArrayCreate([1,10,1,20],varInteger);

 Interface.Test(ParamArray);
end;


 
Koster   (2004-05-16 22:52) [3]

Глюки продолжались... Все предложенные решения выдавали сообщение EOleSysError: "Type Mismatch".
Возможно собака порылась в моей фразе
"Как передавать массивы процедурам (методам класса) DLLки? причем доступные на
запись и на чтение
"
Но проблема была решена.


var
Interface:  OleVariant; // Просто Variant тоже работает.
ParamArray: OleVariant; // Просто Variant тоже работает.
begin
Interface := CreateOleObject("ServerName.Class");

ParamArray := VarArrayCreate([1,10,1,20],varInteger);

Interface.Test(VarArrayRef(ParamArray));
end;


Может кому-нибудь еще пригодится, ведь искал довольно много по интернету, нигде нету передачи массивов, максимум через Import Type Library, статически, как я и делал, а в основном - примеры работы с MS Office безо всяких упоминаний слова "массив".



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

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

Наверх




Память: 0.48 MB
Время: 0.043 c
3-1107157758
Scorpio
2005-01-31 10:49
2005.02.27
While not ADODataSet


6-1103116889
Василий Васильевич Пупкин
2004-12-15 16:21
2005.02.27
Передача данных на сервер методом POST


14-1108014164
syte_ser78
2005-02-10 08:42
2005.02.27
Ошибка при устнаовке Win98


1-1108125073
Piero
2005-02-11 15:31
2005.02.27
Как перехватить mooseWheel


14-1107793461
sten
2005-02-07 19:24
2005.02.27
методы адрессации машинных команд