Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.47 MB
Время: 0.037 c
14-1107793461
sten
2005-02-07 19:24
2005.02.27
методы адрессации машинных команд


14-1107708180
QuasiLamo
2005-02-06 19:43
2005.02.27
Хороший дефрагментатор


1-1108224967
Толян
2005-02-12 19:16
2005.02.27
В рабочее время програмы


1-1107974291
Gost
2005-02-09 21:38
2005.02.27
Как в переменную загнать колличество строк в таблице?


14-1107772094
АлексейК
2005-02-07 13:28
2005.02.27
Построение отчетов





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский