Есть некий объект, который хостится в неком exe-шнике. Надо его поюзать из другого приложения. Вообще-то из NUnit и из С#. При создании объекта сервер благополучно стартует, потом же, при попытке вызвать у этого объекта любой метод летит exception, что QueryInterface() интерфейса у которого хотели спросить метод failed. Смутное подозрение, что что-то с маршалингом не так. Но вот что, и как поправить не ясно...
Первоначально этот экзешник не планировался как СОМ-сервер, прикрутили позже.
Здравствуйте, Denis Titov, Вы писали:
RI>>Первоначально этот экзешник не планировался как СОМ-сервер, прикрутили позже.
DT>А Proxy/Stub к нему прикрутили? Если нет, то вот так и будет ругаться.
exe сервер должен общаться с клиентом из другого процесса, поэтому должна быть еще dll Заглушка/прокси (Proxy/Stub), когда пишешь COM сервер, она должна автоматически генериться, правда как это происходит если прога изначально не была COM сервером — это я затрудняюсь сказать.
Короче, к локальному COM серверу обязательно должна прилагаться Proxy/Stub dll, иначе, клиенту до него (до COM сервера) не достучаться, подробней надо смотреть MSDN или литературу.
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, спасибо.
Здравствуйте, Roman Ivanashko, Вы писали:
RI>Почитал умных статей на RSDN и выяснилось, что dll не обязательна, т.к. у меня интерфейсы [dual] то тут юзается typelib-маршалинг, а код для него динамически создаётся.
Это верно.
RI>Но для него надо чтобы под HKCR/Interface/{XXX} были кое-какие ключики, которых у меня не оказалось, судя по всему из-за того, что не для всех объектов rgs есть и поэтому tlb не регистрировалась.
Это вряд ли. По идее tlb либо регестрится, либо нет, от rgs это зависеть не должно.
Попробуй:
1. Посмотреть tlb вручную OleView
2. Если всё, что нужно есть — зарегестрировать tlb вручную (я знаю только RegisterTypeLib, но, может, есть какая-то утилита)
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