![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
COM. Раннее связывание и ID-связывание. Есть ли реальное отличие?
Aleksey Pavlov © (2002-09-19 12:21:00)Приветствую Мастаков.
На днях, в связи с прочтением одной заметки, возник такой вопрос: какое отличие между ID и ранним связыванием (применительно к технологии COM)?
Я, вообще говоря, всегда думал, что раннее связывание и ID-связывание - это синонимы, т.к. при раннем связывании идентификаторы имён (ID of names) разрешаются на стадии компиляции и заносятся в VTable. Затем через интерфейс VTable осуществляется значительно более быстрый доступ к серверу автоматизации, чем через DispInterface, т.к. нам нет необхрдимости выполнять ф-ию GetIdOfNames интерфейса IDispatch.
В связи с этим, было высказанно мнение, что ID-связывание - это что-то промежуточное между ранним и поздним видом связывания, и что при использовании ID-связывании из Delphi необходимо применять DispInterface, т.к. в данном случае вызов производится через методы IDispatch.
Прошу прояснить ситуацию.
Заранее благодарен.
Digitman (2002-09-20 15:28:00) [21]>Набережных С.
Может, я не очень удачно изложил свое понимание, но оно совпадает с тем, о чем ты говоришь ! Хоть я и не трассировал вызов при таком раскладе - это понятно интуитивно !
Набережных С. (2002-09-20 15:21:00) [22]Здравия желаю!
Когда вызов приходит в заглушку, в ней вызывается метод IRpcStubBuffer.Invoke(var msg:TRPCOLEMESSAGE, Channel:IRpcChannelBuffer), в котором первый параметр - отправленный из прокси через метод IRpcChannelBuffer.SendReceive.
А в структуре TRPCOLEMESSAGE есть поле iMethod, фамилия говорит сама за себя. Но это чисто маршаллинговый внутренний идентификатор, не имеющий отношения к тем, с которыми мы имеем дело в клиенте и сервере. При самостоятельной реализации вы вольны заполнить структуру как вам заблагорассудится - лишь бы потом смогли это понять в заглушке:)
Теперь по поводу стандартного маршаллера. Не имел случая разобраться досконально, поэтому стопроцентно утверждать не могу. Но есть довольно обоснованное подозрение, что он генерит oicf - строки на основании инфы из TLB, которые и используются при маршаллинге VTbl-вызовов. ИМХО.
Digitman (2002-09-20 15:16:00) [23]>vuk
а RPC ,по-твоему, не имеет никакого отношения к маршаллингу ?)
vuk (2002-09-20 13:56:00) [24]to DiamondShark:
Что и требовалось доказать.
to Digitman:
>Вот так я себе это вижу.
На самом деле там кроме RPC ничего нет.
Digitman (2002-09-20 12:55:00) [25]>vuk
>если используются не automation интерфейсы, то.. маршалингом занимается dll-посредник
Это и не вызывает сомнения. Вопрос лишь в том, КАК она это делает) ... если С. работает в ином ВАП ...
И пусть это будет даже не ID-механизм в "чистом" виде (как обязательный как бы атрибут ole automation), все равно взаимодействие между Proxy и Stub (в случае их нахождения в разных ВАП) на этапе маршаллинга происходит с использованием неких предопределенных тем или иным образом уникальных идентификаторов интерфейсных методов: DLL-посредник, отрабатывая вызов Контроллером конкретной своей Stub, формирует маршал-поток, содержащий в т.ч. и в 1-ю очередь некий идент-р метода, и передает его (средствами OLE/COM API) адресату - экземпляру Proxy в ВАП Сервера. Последний же есть по сути обычный маршал-интерпретатор : из потока извлекается тот самый ID, извлекаются параметры, ID"у ставится в соответствие актуальный адрес метода в собственном же ВАП, в TLS настраиваются точки фиксации исключений, параметры и "заготовка" для результата помещаются в стек, и управление передается непосредственно методу. Обратный ход практически не отличается от прямого хода - теперь Proxy и Stub меняются местами в этой цепочке : Proxy выполняет маршаллинг результата, результирующий поток теми же средствами передается в ВАП Stub"а, а Stub выполняет демаршаллинг-интерпретацию результирующего потока, либо возвращая через стек результат и управление коду, вызвавшему Stub-процедуру DLL-посредника, либо генерируя исключение.
Вот так я себе это вижу.
DiamondShark (2002-09-20 12:29:00) [26]
> vuk © (20.09.02 11:19)
Не приходят.
vuk (2002-09-20 11:19:00) [27]to Digitman:
>Вот и получается : какой бы и где бы ни был маршаллер, в любом
>случае на этом этапе трансляции интерфейсного вызова без ID
>никак не обойтись.
Не получается. Потому, что если используются не automation интерфейсы, то, как я уже написал, маршалингом занимается dll-посредник, которая никаких механизмов автоматизации внутри не использует. Потому, что использовать просто нечего.
>в то время как последующаяя трансляция вызова (после VTable-
>преобразования) все равно приводит к маршаллингу (пусть и
>стандартному), использующему так или иначе internal-механизм
>работы диспинтерфейса
Вот на этот счет я очень сильно не уверен. Далее будут толькомои предположения, т.к. я не знаю внутренних механизмов COM. Скорее всего дело обстоит следующим образом: когда клиент создает объект автоматизации вне процесса, подсистема на основании информации из tlb динамически генерирует для каждого интерфейса заглушку, которая на каждой стороне предоставляет возможность работы через VTable интерфейс. Что, в общем-то подтверждается более всокой скоростью работы при использовании VTable доступа к дуальным интерфейсам. На самом деле все это довольно-таки легко проверить. Достаточно посмотреть - приходят ли вызовы в метод Invoke при клиентских вызовах методов через VTable.
Romkin (2002-09-20 10:54:00) [28]2Digitman как я уже постил, полностью согласен с
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/office97/html/SF7A4.asp
однако в Windows SDK нашел следующее определение:
late binding:
The ability to bind names to IDs at run time, rather than compile time.
В принципе, согласуется, речь ведь идет о возможности, но трактовать можно по-разному.
А насчет механизма dispinterface, так interface & dispinterface - разные вещи, и не надо их путать. В ссылке на techvanguards, которую я дал выше, ни слова об dispinterface...
Digitman (2002-09-20 08:20:00) [29]>Набережных С.
Да, внутриконтекстный.
>All
Вот и получается : какой бы и где бы ни был маршаллер, в любом случае на этом этапе трансляции интерфейсного вызова без ID никак не обойтись. Получается, что обращение К. непосредственно к VTable есть суть раннее связывание, в то время как последующаяя трансляция вызова (после VTable-преобразования) все равно приводит к маршаллингу (пусть и стандартному), использующему так или иначе internal-механизм работы диспинтерфейса (а это как бы, по MS, уже есть суть позднее связывание).
Так - чему же верить, господа ?
Набережных С. (2002-09-19 20:19:00) [30]
> vuk © (19.09.02 20:04)
:)))
Я и сам такой:))
vuk (2002-09-19 20:04:00) [31]>Согласись, это несколько расплывчато.
Соглашаюсь. :o) Просто в лом это все писать было. :o)
Набережных С. (2002-09-19 20:01:00) [32]
> подсистема COM Automation
Согласись, это несколько расплывчато. Маршаллингом в любом случае занимается Proxy/Stab DLL. Просто в случае Automation для этого используется обычно(но не обязательно) стандартный маршаллер, использующий в работе информацию из библиотеки типов и находящийся в файле oleaut32.dll. Он же используется, если интерфейс помечен как совместимый с автоматизацией.
vuk (2002-09-19 19:31:00) [33]Если есть tlb и используется Automation, то маршалингом занимается подсистема COM Automation. Под dll-заглушкой я имел в данном случае в виду специальную dll, исходник которой формируется MIDL компилятором по idl-описанию интерфейса.
Набережных С. (2002-09-19 19:26:00) [34]
> vuk © (19.09.02 19:10)
> Да, забыл. Если нет tlb, то маршалингом занимается dll-заглушка.
А если есть, то кто? Иван Федорович Крузенштерн?:)
vuk (2002-09-19 19:10:00) [35]Да, забыл. Если нет tlb, то маршалингом занимается dll-заглушка.
vuk (2002-09-19 19:08:00) [36]>Но каким образом (в принципе !) маршаллинг может осуществляться
>без ID ? Вот как ты себе это мыслишь ?
1. Известно смещение метода в VTable
2. Определен формат вызова методов.
3. Известо количество и типы параметров (tlb)
Мне кажется, что достаточно.
Digitman (2002-09-19 19:04:00) [37]Вообще говоря, господа, MS дает вот такие пояснения :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/office97/html/SF7A4.asp
и здесь я, видимо, расхожусь с ним во мнении
>vuk
> VTable (как и VMT) хранит адреса методов. В случае сервера
> вне процесса там находятся адреса функций - заглушек, при
> помощи которых осуществляется маршалинг вызовов в другой
> процесс.
Да, заглушки, это верно. Но каким образом (в принципе !) маршаллинг может осуществляться без ID ? Вот как ты себе это мыслишь ?
Набережных С. (2002-09-19 19:04:00) [38]
> Digitman © (19.09.02 18:44)
> - при выборе методологии интрапроцессного взаимодействия
> (где маршаллинг нужен как 5-е колесо у телеги)
Ты, вероятно, имел в виду внутриконтекстный вызов?
Набережных С. (2002-09-19 18:56:00) [39]Быстро, однако, посты добавляются:)
Набережных С. (2002-09-19 18:54:00) [40]Весело тут у вас:)))
> Digitman © (19.09.02 17:42)
> >vuk
>
> О VTable (в принципе !) может идти речь только тогда. когда
> К. и С. находятся в едином ВАП. С каких это пор Ecxcel (как
> С.) стал присутствовать в АП твоего процесса (как К.) ?
> Возрази ...
Можно я?:)))
Клиент ведь ВСЕГДА обращается к методам, находящимся в его АП, где бы ни находился сервер - хоть в том-же контексте, хоть на луне :) Просто в последнем случае это будет метод не самого объекта, а его представителя. Proxy - обычный COM-объект, выставляющий интерфейс(или несколько - это детали), семантически эквивалентный одному из интерфейсов замещаемого объекта. В нем точно также используется VTbl. Пройдя через механизмы RPC, вызов попадает в заглушку, которая через интерфейс уже обращается к объекту(опять-же - VTbl). И, кстати, методы IDispatch вызываются так-же - а как же иначе?.