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

Стал экспериментировать с поздним связыванием в 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
09.12.2017, 17:19:59
    #39567076
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
SOFT FOR YOUХочется заполнять такие Variant, которые будут работать по аналогии с OleAutomation
Мой тебе совет, если не нужен именно IDispatch, то просто возьми TInvokeableVariantType.
...
Рейтинг: 0 / 0
09.12.2017, 17:51:42
    #39567084
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
Kazantsev Alexey,

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

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

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

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

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

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

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

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

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

Например, очень крутой тип TDocVariant в Synopse реализован именно через TInvokeableVariantType.
...
Рейтинг: 0 / 0
10.12.2017, 12:26:47
    #39567225
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
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
10.12.2017, 15:44:23
    #39567284
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
В System.Win.ObjComAuto есть TObjectDispatch который реализует IDispatch
Вот пример:
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/TObjectDispatchInvoke_(Delphi)
...
Рейтинг: 0 / 0
10.12.2017, 17:37:45
    #39567324
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
X-CiteВ System.Win.ObjComAuto есть TObjectDispatch который реализует IDispatch
Вот пример:
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/TObjectDispatchInvoke_(Delphi)
точно, он вроде бы ещё с Delphi 7 идёт
...
Рейтинг: 0 / 0
10.12.2017, 19:04:54
    #39567352
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
Самое забавное, что TInvokeableVariantType есть ещё в Delphi 7
Интересно, с какой Delphi он появился )
...
Рейтинг: 0 / 0
10.12.2017, 19:23:56
    #39567362
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDispatch: делаем класс
SOFT FOR YOUИнтересно, с какой Delphi он появился )
С Delphi 6.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IDispatch: делаем класс / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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