Форум: "Corba";
Текущий архив: 2005.10.09;
Скачать: [xml.tar.bz2];
ВнизСтандартный маршалинг в Delphi Найти похожие ветки
← →
Григорьев Антон © (2004-12-20 11:20) [0]Подозреваю, что этот вопрос уже обсуждался здесь, но поиск результата не дал. Началось всё с желания написать COM-сервер на Delphi, совместимый со спецификацией OPC Data Access custom. Она предусматривает стандартный (через proxy/stub dll) маршалинг. В справке Delphi много говорится о маршалинге через библиотеку типов (т.е. универсальном), а вот про стандартный я не нашёл ни слова. Более того, Delphi, похоже, просто не понимает IDL-атрибуты size_is, iid_is и т.п., которые несовместимы с универсальным маршалингом. Неужели на Delphi нельзя написать сервер, использующий эти атрибуты в своих интерфейсах?
← →
VMcL © (2004-12-21 07:02) [1]В справке написано
>Marshaling is provided either through an implementation of the IMarshal interface, or by using a separately generated proxy/stub DLL. Delphi does not support the automatic generation of proxy/stub DLLs.
Не оно?
WBR.
← →
Кролик Енерджайзер (2004-12-21 10:52) [2]Возможно.
Возьми прокси стабы с сайта типа www.opcfoundation.org
Они поставляются в отдельном zip архиве где-то недалеко от документов спецификаций. Зарегестрировав их на машине ты в самой среде выполнишь импорт библиотеки типов и получишь набор интерфейсов на Delphi, которые руками (в обход тайплиба самого сервера) добавишь в список наследования коклассов.
← →
Григорьев Антон © (2004-12-21 11:16) [3]
> VMcL © (21.12.04 07:02) [1]
> Не оно?
Да, уже обнаружил это. Соответственно, вопрос поменялся. Вот есть у меня некий IDL-файл, в котором используются атрибуты size_is, unique и т.д., которые нужны толлько для генерации proxy/stub. Получается, что загнать этот файл в Delphi я не могу - нужно сначала убрать лишние атрибуты. Таким образом, у меня должно быть две версии одного файла - с атрибутами для генерации proxy/stub и без атрибутов для Delphi. И если будут какие-то изменения, мне вручную придётся синхронизировать эти файлы. Очень хотелось бы научить Delphi игнорировать эти атрибуты, чтобы обойтись одной версией файла.
Пока писал, пришла в голову мысль: а что если натравить на IDL-файл Microsoft"овский midl.exe. У него ведь на выходе TLB получается. Может, этот TLB для Delphi подойдёт. Не самое красивое решение, но, по крайней мере, ничего вручную синхронизировать не надо. Буду пробовать.
← →
Кролик Енерджайзер (2004-12-21 11:29) [4]Ты можешь перебросить все OPC интерфейсы в студию и собрать их там, но это уже сделано - просто скачай архив :)
А "size_is и прочее для Delphi выкидывать" лучще оставить. Даже когда ты всё вычистишь и соберёшь - это уже будет другой интерфейс. Твой сервер будет использовать стандартный маршаллер, предположим - ты даже оставишь все GUID"ы как есть. Клиент, ничего не зная о твоём модифицированном сервере (например, SCADA), пошлёт тебе массив данных, а стандартный маршаллер в лучшем случае (не проверял) вызовет модифицированный метод (если вызовет) и передаст единственный элемент (а не массив).
← →
Григорьев Антон © (2004-12-21 12:42) [5]
> Кролик Енерджайзер (21.12.04 11:29) [4]
> Ты можешь перебросить все OPC интерфейсы в студию и собрать
> их там, но это уже сделано - просто скачай архив :)
Вопрос уже перерос OPC. Интересует сам принцип. Пусть есть некоторое описание интерфейсов на IDL. В этом описании есть атрибуты, которые Delphi не понимает, потому что они нужны только для генерации proxy/stub. Как на Delphi написать сервер, реализующий эти интерфейсы?
> Твой сервер будет использовать стандартный маршаллер,
Что в данном случае вы называете стандартным маршаллером? А то у разных авторов стандартным называется маршаллер и через свою proxy/stub, и через oleaut32.dll.
> Клиент, ничего не зная о твоём модифицированном сервере
> (например, SCADA), пошлёт тебе массив данных, а стандартный
> маршаллер в лучшем случае (не проверял) вызовет модифицированный
> метод (если вызовет) и передаст единственный элемент (а
> не массив).
Этого я вообще не понимаю. Пусть у нас есть IDL-файл с описаниями интерфейсов, и есть должным образом зарегистрированная в реестре proxy/stub dll, соответствующая этому файлу. Я делаю такой же IDL-файл, но без лишних атрибутов, и строю кокласс на его основе. Естественно, указывая в визарде, что я не собираюсь использовать oleaut32 для маршалинга. Когда клиент хочет работать с моим сервером, система по реестру определяет, каким proxy маршалируются интерфейсы и использует именно их. А так как моя реализация интерфейсов на бинарном уровне ничем не отличается от той, которая была бы, скажем, при создании сервера на VC++ с оригинальным IDL-файлом, проблем при маршалинге быть не должно. Или я в чём-то неправ?
← →
Кролик Енерджайзер (2004-12-21 13:11) [6]1. Стандартный маршаллер, это тот, который oleaut32.dll
2. Если я не окончательно отстал от жизни, Delphi не работает с IDL как таковыми и "не умеет" генерить стабы. Typelib там редактировался (до 7-ой версии точно) отдельным мастером. Но раз я так понял ты собрался собирать прокси-стаб в студии, то как раз не надо из IDL выкидывать size_is (length_is, first_is, ...) ведь проксятник у тебя и так выйдет Сишный и работать будет именно он. Если же твои интерфейсы OLEAutomation compatible то тогда уже нет никакой нужды лезть в студию. Ведь OLEAutomation сервер можно создать не выходя из Delphi IDE.
← →
Григорьев Антон © (2004-12-21 14:56) [7]
> Кролик Енерджайзер (21.12.04 13:11) [6]
> Но раз я так понял ты собрался собирать прокси-стаб в студии,
> то как раз не надо из IDL выкидывать size_is (length_is,
> first_is, ...) ведь проксятник у тебя и так выйдет Сишный
> и работать будет именно он.
У меня две задачи:
1. Создать на основе IDL proxy/stub
2. Создать на основе того же IDL COM-объект на Delphi, реализующий эти интерфейсы.
Для первой задачи править файл не нужно - это очевидно. Вопрос в том, как решить вторую. Я сейчас вижу два варианта:
а) Взять TLB, который получится при компиляции IDL midl"ом, и попытаться плясать от него. Если это получится - хорошо. До экспериментов у меня просто руки ещё не дошли.
б) Выкинуть из IDL "лишние" атрибуты и построить средствами мастера Delphi tlb на его основе. Нежелательный, как мне кажется, вариант.
Я хочу понять: какой из двух вариантов лучше. И существуют ли ещё какие-то варианты - может, есть ещё лучший способ.
> Typelib там редактировался (до 7-ой версии точно) отдельным
> мастером.
Согласен. Но в этом же мастере есть страница, на которой показывается IDL-код этой библиотеки. И этот код можно вручную редактировать. Так что можно, в принципе, взять IDL-файл и методом copy/paste засунуть его в этот мастер. Вопрос только в том, что мастер поймёт не всякий IDL-код.
← →
Кролик Енерджайзер (2004-12-22 11:30) [8]Да, забудь про вариант б). Собери какой необходимо прокси в студии а в Delphi импорт библиотеки типов из полученной в студии dll.
Борландовцы сделали генерацию idl"а в визарде на основе бинарной библиотеки типов, а не наоборот (как в студии). Текстовое представление typelib"а генерится каждый раз визардом, что называется, в runtime
← →
Григорьев Антон © (2004-12-30 15:02) [9]Начал испытывать вариант 1. Откомпилировал OPCDA.idl, получил OPCDA.tlb. Когда я открываю эту библиотеку в Delphi через File/Open, всё нормально: я вижу интерфейсы и типы, описанные в исходном файле (хотя названия некоторых типов искажены). Но когда я пытаюсь создать новый COM-объект и выбрать интерфейсы из OPCDA.tlb, у меня не получается добавить его в список, который предлагает Delphi. При добавлении ни о каких ошибках Delphi не сообщает, но интерфейсы в списке доступных не появляются. Попытался зарегистрировать opc.tlb вручную через RegSvr32, он пишет "OPCDA.tlb is not an executable file and no registration helper is registered for this type". Просмотр показал, что этот файл начинается с сигнатуры MSFT (вместо MZ, предусмотренной PE-форматом) и действительно не является исполняемым. Как работать с такими tlb-файлами в Delphi? Где можно прочитать о структуре tlb-файлов? Потому что я посмотрел разные tlb-файлы и увидел, что некоторые из них и в самом деле являются PE-файлами.
← →
Кролик Енерджайзер (2004-12-30 16:26) [10]Всё, что делает RegSvr32 при вызове с параметром регистрации (то есть вызов вида "regsvr32.exe <имя.dll>") можно выразить псевдокодом:
1. hInst = LoadLibrary <имя.dll>
2. pFunc = GetProcAddress(hInst, "DllRegisterServer")
3. pFunc();
Попытка загрузить не библиотеку (библиотека типов - это не Dynamic Link Library) - закончилась, разумеется, провалом.
← →
Набережных С. (2005-01-02 08:00) [11]>Григорьев Антон © (30.12.04 15:02) [9]
TRegSvr из поставки Delphi умеет регистрировать библиотеки типов, и исходники ее имеются.
← →
Григорьев Антон © (2005-01-10 12:26) [12]С практической точки зрения мне всё более-менее ясно: нужно создать COM-объект без библиотеки типов, добавить к проекту OPCDA.tlb, и вручную добавить коклассу реализацию нужных интерфейсов. Но полного понимания всё равно нет :( Два моих основных вопроса:
1. Если regsvr32 не умеет регистрировать tlb, почему в справке Delphi написано: RegSvr32.exe is a standard Windows utility for registering and unregistering servers and type libraries.?
2. Почему Delphi в упор не видит интерфейсов, описанных в OPCDA.tlb? Более того, если зарегистрировать эту библиотеку типов с помощью TRegSvr, регистрация проходит нормально, информация о библиотеке типов появляется в реестре, но информация об интерфейсах туда не заносится. В принципе, это правильно: т.к. для этих интерфейсов исползуется не универсальный, а стандартный маршалинг, они регистриуются, не при при регистрации библиотеки типов, а при регистрации proxy/stub dll. Но как система узнаёт о том, что интерфейсы, описанные в OPCDA.tlb, надо при регистрации игнорировать? У меня подозрение, что это происходит потому, что интерфейсы в исходном файле OPCDA.idl описаны вне тега library.
Короче, я понял, что мне надо бы как следует разобраться с IDL. А то в общих чертах всё понятно, а как начинаю копать поглубже, выясняется, что ничего я не понимаю. Не знает ли кто хорошей ссылки, по которой можно почитать описание Microsoft IDL со всеми тонкостями?
← →
Набережных С. (2005-01-10 17:34) [13]Если я правильно помню, в tlb попадет только то, что описано либо используется внутри тэга library, вроде бы так, остальное в tlb не включается. Для регистрации под универсальный маршалинг служит атрибут oleautomation - опять же, если ничего не путаю.
А в данном случае не все ли равно? По любому потребуется Proxy/Stub dll, если конечно не использовать IMarshal.
Имхо, в MSDN все это очень прилично расписано. Смотри раздел Microsoft Interface Definition Language.
← →
Григорьев Антон © (2005-01-11 10:57) [14]
> Если я правильно помню, в tlb попадет только то, что описано
> либо используется внутри тэга library, вроде бы так, остальное
> в tlb не включается.
Не совсем. Когда я открываю этот tlb в Delphi, то в OPCDA_TLB.pas, сгенерированный средой, попадают все типы и интерфейсы. Значит, они там есть.
> А в данном случае не все ли равно?
С практической точки зрения - всё равно. Просто возникло желание разобраться со всем этим как следует.
P.S. Я ведь людей учу :) Стандартам OPC курс посвящён, заодно и COM/DCOM слегка объясняю. Ученики, бывает, самые разные вопросы задают. Не хочется отвечать им по принципу "делай так, и будет тебе счастие", хочется рассказать всё как следует. Вот и копаю :)
← →
Erik1 © (2005-01-13 11:06) [15]А непроще самому написать реализацию IMarshal и сделать его похожий на стандартный?
← →
Григорьев Антон © (2005-01-13 17:53) [16]
> Erik1 © (13.01.05 11:06) [15]
> А непроще самому написать реализацию IMarshal и сделать
> его похожий на стандартный?
Если говорить конкретно об OPC, то не проще - там уже есть готовая proxy/stub dll, которая является частью стандарта, и использование доморощенных средств может привести к несовместимости.
Страницы: 1 вся ветка
Форум: "Corba";
Текущий архив: 2005.10.09;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.012 c