powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IDispatch: делаем класс
12 сообщений из 12, страница 1 из 1
IDispatch: делаем класс
    #39567071
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет

Стал экспериментировать с поздним связыванием в Variant
Хочется заполнять такие Variant, которые будут работать по аналогии с OleAutomation

Выяснил, что нужно создать экземпляр IDispatch и присвоить его варианту
С TInterfacedObject всё понятно, но как заполнять специфичные функции - пока не осилил. Доку читал

Кто сталкивался или хотя бы догадывается, как надо реализовывать, давайте разберёмся.
Предлагаю в качестве теста реализовать следующий "интерфейс":
Код: pascal
1.
2.
 function Test(const X: Integer): Int64;
 property Value: string read GetValue write SetValue;



На всякий случай повторяю интерфейс IDispatch:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
  IDispatch = interface(IUnknown)
    ['{00020400-0000-0000-C000-000000000046}']
    function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
      NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
      Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
  end;
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567076
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUХочется заполнять такие Variant, которые будут работать по аналогии с OleAutomation
Мой тебе совет, если не нужен именно IDispatch, то просто возьми TInvokeableVariantType.
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567084
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Огонь, спасибо!
То что нужно

С другой стороны делается очень много реаллоков памяти, что не есть гуд
И разобраться с IDispatch будет интересно
Так что если кому интересно - подключайтесь )
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567091
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUИ разобраться с IDispatch будет интересно
Там всё просто. Первые два метода можно не реализовывать (result := E_NOTIMPL). GetIDsOfNames должен уметь возвращать числовой идентификатор(ы) по имени сущности (метода или свойства). Invoke должен по числовому идентификатору оперировать сущностью. Например, вызов метода от варианта хранящего IDispatch сводится в вызову этих двух методов: сперва по имени запрашивается идентификатор, потом по идентификатору просят сделать вызов. Если вызовы происходят через dispinterface, то для сущностей у которых указан идентификатор (dispId) запрос идентификатора делаться не будет, а будет сразу запрос на вызов. Общий принцип работы такой.
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567188
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

С GetIDsOfNames я разобрался
Не понятно только, зачем массив имён
И зачем Delphi для вызова с поздним связыванием делает столько вещей: создаёт массив WideString, заполняет из UTF8.

А зачем вообще первые два метода?

И с Invoke, конечно, треш. Как определить, это GetProperty или SetProperty, есть ли в этом свойстве параметр, или это функция, или процедура? С TInvokableVariantType как-то всё проще :). Кстати да, Variant-вызов позволяет явно указать аргументы, которые ты заполняешь. Как их (имена/значения) узнать в Invoke?
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567216
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, Invoke можно сделать по аналогии с TInvokableVariantType
И вообще, если говорить о скорости, то лучше делать свой TCustomVariantType и переопределять Invoke, там имя можно найти в PAnsiChar и не преобразовывать в Unicode/WideString. А для сложных типов проще конечно взять TInvokableVariantType

Вопрос закрыт
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567218
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUKazantsev Alexey,

С GetIDsOfNames я разобрался
Не понятно только, зачем массив имён
И зачем Delphi для вызова с поздним связыванием делает столько вещей: создаёт массив WideString, заполняет из UTF8.

А зачем вообще первые два метода?

И с Invoke, конечно, треш. Как определить, это GetProperty или SetProperty, есть ли в этом свойстве параметр, или это функция, или процедура? С TInvokableVariantType как-то всё проще :). Кстати да, Variant-вызов позволяет явно указать аргументы, которые ты заполняешь. Как их (имена/значения) узнать в Invoke?

Например, очень крутой тип TDocVariant в Synopse реализован именно через TInvokeableVariantType.
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567225
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUНе понятно только, зачем массив имён
Чтобы за один вызов можно было получить несколько идентификаторов. Я сейчас не помню, как именно поступает дельфя в случае вызова:
Код: pascal
1.
v.namepsace1.namespace2.namespace3.method();


но, это, один из тех случаев, когда идентификаторы можно запросить одним вызовом.

SOFT FOR YOUИ зачем Delphi для вызова с поздним связыванием делает столько вещей: создаёт массив WideString, заполняет из UTF8.
IDispatch это системный интерфейс. В виндах он является основным интерфейсом автоматизации. Поэтому всё делается исходя из требований предъявляемых к таким интерфейсам (WideString, OleVariant; всё для совместимости с системными требованиями). Этот интерфейс можно использовать вне процесса, поэтому без безопасных типов тут не обойтись.

SOFT FOR YOUА зачем вообще первые два метода?
Для того, чтобы объект автоматизации мог экспортировать информацию о самом себе и используемых им типов.

SOFT FOR YOUИ с Invoke, конечно, треш. Как определить, это GetProperty или SetProperty, есть ли в этом свойстве параметр, или это функция, или процедура?
Всё определяется параметрами передаваемыми в Invoke.

SOFT FOR YOUИ вообще, если говорить о скорости, то лучше делать свой TCustomVariantType и переопределять Invoke, там имя можно найти в PAnsiChar и не преобразовывать в Unicode/WideString.
Если уж говорить о скорости, то работа с IDispatch через dispinterface, наверняка, порвёт всё прочие варианты:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 DIntf = dispinterface
 [SDIntf_IID]
 functon HelloWorld(A : Integer) : Integer; dispId 1024;
 end;
...
var intf : DIntf;
v : variant;
begin
 v := someInitialization;
 ...
 intf := IDispatch(v) as DIntf;
 intf.HelloWorld(512);
end;
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567284
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В System.Win.ObjComAuto есть TObjectDispatch который реализует IDispatch
Вот пример:
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/TObjectDispatchInvoke_(Delphi)
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567324
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteВ System.Win.ObjComAuto есть TObjectDispatch который реализует IDispatch
Вот пример:
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/TObjectDispatchInvoke_(Delphi)
точно, он вроде бы ещё с Delphi 7 идёт
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567352
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самое забавное, что TInvokeableVariantType есть ещё в Delphi 7
Интересно, с какой Delphi он появился )
...
Рейтинг: 0 / 0
IDispatch: делаем класс
    #39567362
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUИнтересно, с какой Delphi он появился )
С Delphi 6.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IDispatch: делаем класс
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]