COM сервер в exe
От: Roman Ivanashko  
Дата: 07.05.04 09:07
Оценка:
Есть некий объект, который хостится в неком exe-шнике. Надо его поюзать из другого приложения. Вообще-то из NUnit и из С#. При создании объекта сервер благополучно стартует, потом же, при попытке вызвать у этого объекта любой метод летит exception, что QueryInterface() интерфейса у которого хотели спросить метод failed. Смутное подозрение, что что-то с маршалингом не так. Но вот что, и как поправить не ясно...
Первоначально этот экзешник не планировался как СОМ-сервер, прикрутили позже.
Re: COM сервер в exe
От: Denis Titov Россия  
Дата: 07.05.04 09:38
Оценка:
RI>Первоначально этот экзешник не планировался как СОМ-сервер, прикрутили позже.

А Proxy/Stub к нему прикрутили? Если нет, то вот так и будет ругаться.
Re[2]: COM сервер в exe
От: Roman Ivanashko  
Дата: 07.05.04 09:46
Оценка:
Здравствуйте, Denis Titov, Вы писали:

RI>>Первоначально этот экзешник не планировался как СОМ-сервер, прикрутили позже.


DT>А Proxy/Stub к нему прикрутили? Если нет, то вот так и будет ругаться.


Гм... IDL прикрутили. Этого не хватит?
Re[3]: COM сервер в exe
От: Denis Titov Россия  
Дата: 07.05.04 10:28
Оценка:
RI>Гм... IDL прикрутили. Этого не хватит?

exe сервер должен общаться с клиентом из другого процесса, поэтому должна быть еще dll Заглушка/прокси (Proxy/Stub), когда пишешь COM сервер, она должна автоматически генериться, правда как это происходит если прога изначально не была COM сервером — это я затрудняюсь сказать.

Короче, к локальному COM серверу обязательно должна прилагаться Proxy/Stub dll, иначе, клиенту до него (до COM сервера) не достучаться, подробней надо смотреть MSDN или литературу.
Re[4]: COM сервер в exe
От: Roman Ivanashko  
Дата: 07.05.04 12:15
Оценка:
Здравствуйте, Denis Titov, Вы писали:


RI>>Гм... IDL прикрутили. Этого не хватит?


DT>exe сервер должен общаться с клиентом из другого процесса, поэтому должна быть еще dll Заглушка/прокси (Proxy/Stub), когда пишешь COM сервер, она должна автоматически генериться, правда как это происходит если прога изначально не была COM сервером — это я затрудняюсь сказать.


DT>Короче, к локальному COM серверу обязательно должна прилагаться Proxy/Stub dll, иначе, клиенту до него (до COM сервера) не достучаться, подробней надо смотреть MSDN или литературу.


Почитал умных статей на RSDN и выяснилось, что dll не обязательна, т.к. у меня интерфейсы [dual] то тут юзается typelib-маршалинг, а код для него динамически создаётся. Но для него надо чтобы под HKCR/Interface/{XXX} были кое-какие ключики, которых у меня не оказалось, судя по всему из-за того, что не для всех объектов rgs есть и поэтому tlb не регистрировалась.

А за идею порыть в направлении proxy/stub, спасибо.
Re[5]: COM сервер в exe
От: SergH Россия  
Дата: 07.05.04 14:11
Оценка:
Здравствуйте, Roman Ivanashko, Вы писали:

RI>Почитал умных статей на RSDN и выяснилось, что dll не обязательна, т.к. у меня интерфейсы [dual] то тут юзается typelib-маршалинг, а код для него динамически создаётся.


Это верно.

RI>Но для него надо чтобы под HKCR/Interface/{XXX} были кое-какие ключики, которых у меня не оказалось, судя по всему из-за того, что не для всех объектов rgs есть и поэтому tlb не регистрировалась.


Это вряд ли. По идее tlb либо регестрится, либо нет, от rgs это зависеть не должно.
Попробуй:

1. Посмотреть tlb вручную OleView
2. Если всё, что нужно есть — зарегестрировать tlb вручную (я знаю только RegisterTypeLib, но, может, есть какая-то утилита)
Делай что должно, и будь что будет
Re[6]: COM сервер в exe
От: Roman Ivanashko  
Дата: 07.05.04 15:15
Оценка:
RI>>Но для него надо чтобы под HKCR/Interface/{XXX} были кое-какие ключики, которых у меня не оказалось, судя по всему из-за того, что не для всех объектов rgs есть и поэтому tlb не регистрировалась.

SH>Это вряд ли. По идее tlb либо регестрится, либо нет, от rgs это зависеть не должно.


На самом деле, вроде, не совсем так.
Путём копания в недрах ATL выяснилось следующее:
Регистрация запускается при помощи CComModule::.RegisterServer(TRUE), которая собственно бежит по entries в ObjMap для модуля и вызывает для каждого объекта UpdateRegistryFromResource(IDR_XXX,...), только после этого регистрируется tlb(если надо), но только в том случае, если все предыдущие вызовы UpdateRegistry для каждого Entrie были успешны.
Сама регистрация осуществляется RegisterTypeLib().
Так как один rgs у меня был с ошибкой, то она ничего не говорила, но RegisterTypeLib не вызывала.
Собственно всё это можно увидеть в AtlModuleRegisterServer из ATLBase.h
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.