Форум: "Corba";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
ВнизПередача массивом 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 вся ветка
Форум: "Corba";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.038 c