Проблема с маршалингом между сервисом и клиентом
От: smartik17  
Дата: 14.10.10 10:49
Оценка:
Доброго времени суток!
Понимаю что вопрос заезжен, но найти ответа именно для моей проблемы не могу

Задача состоит в следующем:
создать:
— singleton COM-Server (Service)
— клиент MFC приложение.
обеспечить:
— общение между клиентом и сервисом через СОМ и Connection Point

Проблема в том что тут необходимо сделать общение между 2 процессами.

Помогите разобраться.

У меня есть тестовый проект который частично реализует эту схему. Вот он: http://files.rsdn.ru/94313/talk_between_Processes.zip
Но проблема в том что Сервис не может получить интерфейс клиента:

STDMETHODIMP CMyService::ClientStarted(IUnknown* pIUnknown)
{
    HRESULT hr = E_FAIL;
    CComPtr<IClient2> spIClient;
    hr = pIUnknown->QueryInterface(IID_IClient2, (void**)&spIClient);
    return hr;
}


hr = E_NOINTERFACE.

Может кто-то подскажет в чём причина? или есть рабочий пример ?

Спасибо!
Re: Проблема с маршалингом между сервисом и клиентом
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.10.10 11:44
Оценка:
Здравствуйте, smartik17, Вы писали:

S>hr = E_NOINTERFACE.


S>Может кто-то подскажет в чём причина? или есть рабочий пример ?


А ты клиент и сервис регистрируешь в Реестре, т.е. запускаешь ли их с ключом -RegServer? Обычная ошибка E_NOINTERFACE заключается в том, что отсутствует код маршаллинга для интерфейса.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Проблема с маршалингом между сервисом и клиентом
От: smartik17  
Дата: 14.10.10 13:12
Оценка:
Vi2>А ты клиент и сервис регистрируешь в Реестре, т.е. запускаешь ли их с ключом -RegServer? Обычная ошибка E_NOINTERFACE заключается в том, что отсутствует код маршаллинга для интерфейса.

В Pos-Build events проекта TestMyService прописано "$(TargetPath)" /RegServer
Этого ведь достаточно?
Re[3]: Проблема с маршалингом между сервисом и клиентом
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.10.10 14:00
Оценка:
Здравствуйте, smartik17, Вы писали:

S>В Pos-Build events проекта TestMyService прописано "$(TargetPath)" /RegServer

S>Этого ведь достаточно?

Для запуска сервера и регистрации его библиотек для маршаллинга — да. Но клиент у тебя тоже СОМ сервер — он также должен себя регистрировать.

Руками зарегистрируй оба приложения и посмотри результат.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Проблема с маршалингом между сервисом и клиентом
От: smartik17  
Дата: 14.10.10 15:05
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, smartik17, Вы писали:


S>>В Pos-Build events проекта TestMyService прописано "$(TargetPath)" /RegServer

S>>Этого ведь достаточно?

Vi2>Для запуска сервера и регистрации его библиотек для маршаллинга — да. Но клиент у тебя тоже СОМ сервер — он также должен себя регистрировать.


Vi2>Руками зарегистрируй оба приложения и посмотри результат.
Re[4]: Проблема с маршалингом между сервисом и клиентом
От: Jolly Roger  
Дата: 15.10.10 02:58
Оценка: +1
Здравствуйте, Vi2, Вы писали:

Vi2>Для запуска сервера и регистрации его библиотек для маршаллинга — да. Но клиент у тебя тоже СОМ сервер — он также должен себя регистрировать.


А зачем клиента регистрировать? Если IClient2 декларирован сервером, как и делается для callback-интерфейсов, то достаточно регистрации сервера на хосте сервера и библиотеки типов сервера на хосте клиента (ну или маршалера, если библиотечный не используется), а если его декларирует клиент, то это скорее ошибка проектирования

Если правильно помню, то такое возможно из-за настроек безопасности — у сервера нет прав на доступ к клиентским объектам. В этом случае можно конечно зарегистрировать AppId клиента на серверном хосте и настроить ему защиту, но это неудобно, нужно, ЕМНИП, создавать AppId для каждого клиентского хоста. Обычно достаточно отключить защиту на клиенте вызовом CoInitializeSecutity, в подавляющем большинстве случаев для коллбэков это допустимо и не снизит защищённость системы. По-моему так
"Нормальные герои всегда идут в обход!"
Re[5]: Проблема с маршалингом между сервисом и клиентом
От: Vi2 Удмуртия http://www.adem.ru
Дата: 15.10.10 05:58
Оценка: +1
Здравствуйте, Jolly Roger, Вы писали:

JR>А зачем клиента регистрировать? Если IClient2 декларирован сервером, как и делается для callback-интерфейсов, то достаточно регистрации сервера на хосте сервера и библиотеки типов сервера на хосте клиента (ну или маршалера, если библиотечный не используется), а если его декларирует клиент, то это скорее ошибка проектирования


Я ориентировался на существующую архитектуру и, если бы всё получилось, то можно было в дальнейшем порекомендовать перейти именно на такую структуру: интерфейс клиента должен определять сервер, поскольку он вызывает методы клиента. А так просто грузить человека, когда у него и так проблемы, не в моих правилах.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Проблема с маршалингом между сервисом и клиентом
От: Jolly Roger  
Дата: 15.10.10 07:11
Оценка:
Здравствуйте, Vi2, Вы писали:

Со всем согласен, кроме определения "просто грузить" Если ТС допускает ошибку, даже предположительно, то лучше на неё сразу указать — ведь ТС за этим и задал вопрос, разве нет?

Вы, вероятно, пытались таким образом прояснить, где декларирован интерфейс. Но я вот это сразу не понял, боюсь, ТС тоже Прямо заданный вопрос скорее всего выглядел-бы более однозначно, но это только лишь моё частное мнение, и я ни в коем случае не настаиваю на его абсолютной правоте
"Нормальные герои всегда идут в обход!"
Re[5]: Проблема с маршалингом между сервисом и клиентом
От: Jolly Roger  
Дата: 15.10.10 07:19
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

Я тут допустил ошибку, которую только сейчас заметил AppId клиента надо создавать на каждом клиентском хосте, там и настраивать защиту. В принципе, ничего страшного, но потребует инсталляции каждого клиента.
"Нормальные герои всегда идут в обход!"
Re[7]: Проблема с маршалингом между сервисом и клиентом
От: Vi2 Удмуртия http://www.adem.ru
Дата: 15.10.10 08:41
Оценка: 6 (1)
Здравствуйте, Jolly Roger, Вы писали:

JR>Вы, вероятно, пытались таким образом прояснить, где декларирован интерфейс. Но я вот это сразу не понял, боюсь, ТС тоже Прямо заданный вопрос скорее всего выглядел-бы более однозначно, но это только лишь моё частное мнение, и я ни в коем случае не настаиваю на его абсолютной правоте


Я ориентировался на содержимое проекта, указанного в первом посте, однако я его не открывал в Студии, просто просмотрел скоренько.

Выполнение клиента как сервера может иметь смысл. Успешный вызов CoCreateInstance(CLSID_Client2,...) в самом клиенте сыграл злую шутку, т.к. ехе-клиент регистрирует свои фабрики класса, и для CLSID_Client2 она оказывалась доступной БЕЗ регистрации в Реестре, однако маршаллинг клиентских интерфейсов отсутствовал, но этот маршаллинг и не требовался для самого клиента. Но почему Студия не оформила регистрацию в ПостБилде для клиента — не понятно, ведь это полноценный СОМ-сервер. Хотя может это и к лучшему, потому что при использовании на другом компе могли возникнуть такие же сложности.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: Проблема с маршалингом между сервисом и клиентом
От: Jolly Roger  
Дата: 15.10.10 09:02
Оценка:
Здравствуйте, Vi2, Вы писали:

Я, признаться, проект не открывал, поленился Ну если у него несколько взаимодействующих COM-серверов, то вероятно есть смысл вынести все декларации интерфейсов в отдельный проект, отдельную библиотеку типов. В будущем это может сильно облегчить жизнь, правда может и осложнить Ведь всё равно каждый из них должен иметь информацию обо всех интерфейсах, логично собрать её в одном месте, под контролем одного издателя. Либо переходить на использование диспинтерфейсов.
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.