Доброго времени суток!
Понимаю что вопрос заезжен, но найти ответа именно для моей проблемы не могу
Задача состоит в следующем:
создать:
— singleton COM-Server (Service)
— клиент MFC приложение.
обеспечить:
— общение между клиентом и сервисом через СОМ и Connection Point
Проблема в том что тут необходимо сделать общение между 2 процессами.
Здравствуйте, smartik17, Вы писали:
S>hr = E_NOINTERFACE.
S>Может кто-то подскажет в чём причина? или есть рабочий пример ?
А ты клиент и сервис регистрируешь в Реестре, т.е. запускаешь ли их с ключом -RegServer? Обычная ошибка E_NOINTERFACE заключается в том, что отсутствует код маршаллинга для интерфейса.
Vi2>А ты клиент и сервис регистрируешь в Реестре, т.е. запускаешь ли их с ключом -RegServer? Обычная ошибка E_NOINTERFACE заключается в том, что отсутствует код маршаллинга для интерфейса.
В Pos-Build events проекта TestMyService прописано "$(TargetPath)" /RegServer
Этого ведь достаточно?
Re[3]: Проблема с маршалингом между сервисом и клиентом
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, smartik17, Вы писали:
S>>В Pos-Build events проекта TestMyService прописано "$(TargetPath)" /RegServer S>>Этого ведь достаточно?
Vi2>Для запуска сервера и регистрации его библиотек для маршаллинга — да. Но клиент у тебя тоже СОМ сервер — он также должен себя регистрировать.
Vi2>Руками зарегистрируй оба приложения и посмотри результат.
Re[4]: Проблема с маршалингом между сервисом и клиентом
Здравствуйте, Vi2, Вы писали:
Vi2>Для запуска сервера и регистрации его библиотек для маршаллинга — да. Но клиент у тебя тоже СОМ сервер — он также должен себя регистрировать.
А зачем клиента регистрировать? Если IClient2 декларирован сервером, как и делается для callback-интерфейсов, то достаточно регистрации сервера на хосте сервера и библиотеки типов сервера на хосте клиента (ну или маршалера, если библиотечный не используется), а если его декларирует клиент, то это скорее ошибка проектирования
Если правильно помню, то такое возможно из-за настроек безопасности — у сервера нет прав на доступ к клиентским объектам. В этом случае можно конечно зарегистрировать AppId клиента на серверном хосте и настроить ему защиту, но это неудобно, нужно, ЕМНИП, создавать AppId для каждого клиентского хоста. Обычно достаточно отключить защиту на клиенте вызовом CoInitializeSecutity, в подавляющем большинстве случаев для коллбэков это допустимо и не снизит защищённость системы. По-моему так
"Нормальные герои всегда идут в обход!"
Re[5]: Проблема с маршалингом между сервисом и клиентом
Здравствуйте, Jolly Roger, Вы писали:
JR>А зачем клиента регистрировать? Если IClient2 декларирован сервером, как и делается для callback-интерфейсов, то достаточно регистрации сервера на хосте сервера и библиотеки типов сервера на хосте клиента (ну или маршалера, если библиотечный не используется), а если его декларирует клиент, то это скорее ошибка проектирования
Я ориентировался на существующую архитектуру и, если бы всё получилось, то можно было в дальнейшем порекомендовать перейти именно на такую структуру: интерфейс клиента должен определять сервер, поскольку он вызывает методы клиента. А так просто грузить человека, когда у него и так проблемы, не в моих правилах.
Со всем согласен, кроме определения "просто грузить" Если ТС допускает ошибку, даже предположительно, то лучше на неё сразу указать — ведь ТС за этим и задал вопрос, разве нет?
Вы, вероятно, пытались таким образом прояснить, где декларирован интерфейс. Но я вот это сразу не понял, боюсь, ТС тоже Прямо заданный вопрос скорее всего выглядел-бы более однозначно, но это только лишь моё частное мнение, и я ни в коем случае не настаиваю на его абсолютной правоте
"Нормальные герои всегда идут в обход!"
Re[5]: Проблема с маршалингом между сервисом и клиентом
Я тут допустил ошибку, которую только сейчас заметил AppId клиента надо создавать на каждом клиентском хосте, там и настраивать защиту. В принципе, ничего страшного, но потребует инсталляции каждого клиента.
"Нормальные герои всегда идут в обход!"
Re[7]: Проблема с маршалингом между сервисом и клиентом
Здравствуйте, Jolly Roger, Вы писали:
JR>Вы, вероятно, пытались таким образом прояснить, где декларирован интерфейс. Но я вот это сразу не понял, боюсь, ТС тоже Прямо заданный вопрос скорее всего выглядел-бы более однозначно, но это только лишь моё частное мнение, и я ни в коем случае не настаиваю на его абсолютной правоте
Я ориентировался на содержимое проекта, указанного в первом посте, однако я его не открывал в Студии, просто просмотрел скоренько.
Выполнение клиента как сервера может иметь смысл. Успешный вызов CoCreateInstance(CLSID_Client2,...) в самом клиенте сыграл злую шутку, т.к. ехе-клиент регистрирует свои фабрики класса, и для CLSID_Client2 она оказывалась доступной БЕЗ регистрации в Реестре, однако маршаллинг клиентских интерфейсов отсутствовал, но этот маршаллинг и не требовался для самого клиента. Но почему Студия не оформила регистрацию в ПостБилде для клиента — не понятно, ведь это полноценный СОМ-сервер. Хотя может это и к лучшему, потому что при использовании на другом компе могли возникнуть такие же сложности.
Я, признаться, проект не открывал, поленился Ну если у него несколько взаимодействующих COM-серверов, то вероятно есть смысл вынести все декларации интерфейсов в отдельный проект, отдельную библиотеку типов. В будущем это может сильно облегчить жизнь, правда может и осложнить Ведь всё равно каждый из них должен иметь информацию обо всех интерфейсах, логично собрать её в одном месте, под контролем одного издателя. Либо переходить на использование диспинтерфейсов.