RTD - создание образца COM DLL в COM exe - PullRequest
2 голосов
/ 14 февраля 2009

Я планирую превратить свое существующее приложение в RTD-сервер .

Приложение в настоящее время написано на C ++, и хотя я в конечном итоге перенесу его на C # / Mono, я хочу иметь возможность добавить функциональность RTD с C ++.

Я нашел несколько примеров кода (MSVCRTDServer) и этот сайт: http://weblogs.asp.net/kennykerr/archive/2008/10/29/excel-rtd-server-in-c.aspx

К сожалению, это DLL, и я забыл все, что я знал о COM (хорошее избавление) давным-давно.

Как мне включить примеры DLL в EXE? Очевидно, речь идет об упаковке COM-сервера в EXE, а не в DLL.

EDIT:

Обратите внимание, что существующее приложение имеет MFC GUI.

EDIT:

Предполагается, что будет использоваться существующее приложение с графическим интерфейсом - клиентам приложения COM / RTD не нужно запускать приложение. (Хотя я не буду отрицать, что это было бы хорошо)

По сути, я хочу реализовать интерфейс IRTDServer с моими собственными данными, чтобы Excel (или другие приложения) могли получать доступ к динамическим данным, которые предоставляет приложение. (Это программа, которая обращается к устройству с последовательным портом - это устройство имеет статус / состояние, которое изменяется, и я хочу иметь возможность обновлять клиенты об изменениях асинхронно)

Итак, мне нужно создать COM-объект и зарегистрировать его, чтобы клиенты могли его «увидеть».

Я не уверен, как добавить COM-объект в exe и заставить этот COM-объект реализовать существующий / заранее определенный интерфейс.

EDIT Я получил награду за это, чтобы получить примеры кода. По-видимому, я слишком ленив и глуп (или, может быть, это просто чрезмерная неприязнь к СОМ), чтобы начать с существующего ответа Франци Пенова. (что очень полезно и отличное начало)

Итак, в основном я ищу:

код, чтобы взять мое существующее диалоговое приложение MFC с несколькими запущенными потоками и превратить его в RTD-сервер (с таким же пользовательским интерфейсом)

Все, что сотворено и CoThisandthat, и т. Д. Где я могу поместить этот код в моем exe? Как мне расширить / внедрить IRTD?

До и после примера приложения MFC hello world (на основе диалогового окна) будет получен принятый ответ.

  1. Перед приложением со всем исходным кодом для диалогового приложения MFC.
  2. Приложение «после», основанное на приложении MFC на шаге 1, которое реализует интерфейс RTD-сервера и весь его источник. (все файлы проекта, исходные тексты и т. д.)
  3. шаги, предпринятые в GUI / visual studio и в других случаях для создания шага 2 из шага 1. (Созданы IDL и другие файлы.)

В идеале это предусмотрено для VS2008, но любая версия будет работать.

Спасибо.

Ответы [ 2 ]

3 голосов
/ 14 февраля 2009

РЕДАКТИРОВАТЬ: Чувак, я не касался MFC с 2000 года. Я надеялся остаться таким до конца своей жизни. :-) В любом случае ...

По-видимому, волшебники развивались с прошлого века. Следующие шаги для добавления поддержки ATL COM и приложения MFC предназначены для VS 2008.

  1. Создание простого приложения на основе диалогового окна MFC под названием MFCTest. НЕ установите флажок Автоматизация в мастере.
  2. Щелкните правой кнопкой мыши проект и выберите Добавить / Класс ... В диалоговом окне выберите Простой объект ATL. Вы получите предупреждение о том, что в проект будет добавлена ​​поддержка ATL.
  3. Откроется новый мастер с опциями для нового объекта ATL.

Вы должны быть сделаны.

Честно говоря, я не вижу смысла размещать здесь сгенерированный мастером код. Но если у вас есть дополнительные вопросы по отдельным частям этого кода, опубликуйте их в SO, и я вам помогу.


РЕДАКТИРОВАТЬ: Это постепенно превращается в статью. Если мы продолжим в том же духе, я мог бы даже опубликовать книгу. : -)

Если у вас есть простой объект ATL, интегрированный в проект MFC, вы можете добавить к нему интерфейс RTD. Вам нужно будет оба наследовать от интерфейса и добавить его в COM_INTERFACE_MAP. Поскольку интерфейс RTD представляет собой интерфейс IDispatch, вам придется наследовать ваш класс от IDispatchImpl <> и добавить IDispatch к COM_INTERFACE_MAP, используя COM_INTERFACE_ENTRY2 (чтобы указать, что он реализован через IRtdServer.

Я не очень знаком с тем, как работает RTD. Вам также может понадобиться добавить поддержку точек подключения COM в ваш класс, если Excel нужно добавить подписку на ваши обновления. Вот также ссылка для обновления ваших точек подключения в ATL знание.

Кстати, я наткнулся на это сообщение в блоге, в котором есть C ++ определения двух интерфейсов RTD . Возможно, они у вас уже есть, но я решил добавить их для полноты картины.


Самый простой способ - создать новый проект ATL EXE с помощью мастера VS и разрешить ему принимать участие в регистрации и управлении процессом. Остальное не так уж и отличается.

Если вам нужен конкретный образец, чтобы начать свое путешествие обратно в страну COM вне процесса, вы можете посмотреть на LABRADOR .

Несколько ссылок, которые могут вас заинтересовать:

РЕДАКТИРОВАТЬ: Если вам просто нужно знать, как зарегистрировать объект в вашем EXE с помощью COM, чтобы клиентские приложения могли CocreateInstance его, посмотрите CoRegisterClassObject . Однако:

  • объект должен быть COM-объектом
  • вам нужно реализовать фабрику классов для этого
  • если вы хотите, чтобы управление процессами (т. Е. COM запускало ваше приложение по требованию), необходимо зарегистрировать ClassID в реестре
  • если клиент собирается создать его через ProgID, ProgID необходимо зарегистрировать в реестре
  • вам может понадобиться пользовательский прокси / заглушка dll, если вы делаете пользовательское упорядочение
  • если ваше приложение имеет пользовательский интерфейс, вам придется изменить логику выключения, чтобы, когда пользователь закрывает пользовательский интерфейс, приложение не выходило до тех пор, пока не будет выпущена последняя ссылка COM на ваши объекты

РЕДАКТИРОВАТЬ 2: Я бы по-прежнему предлагал вам взглянуть на образец ATL вне процесса и на скелет, который сгенерирует мастер ATL, чтобы понять последовательность операций. Однако вам может потребоваться немного углубиться в код ATL, чтобы увидеть, что именно происходит.

Вот краткая версия процесса:

При запуске приложению необходимо проверить наличие определенного аргумента командной строки - / embedded . Если этот аргумент присутствует, это означает, что приложение запускается COm в ответ на вызов CoCO. В этот момент приложение может не отображать свой пользовательский интерфейс.

Независимо от того, показывает ли приложение пользовательский интерфейс или нет, оно должно регистрировать фабрики классов для любых объектов COM, которые оно предоставляет через API CoRegisterClassObject, о котором я упоминал выше.

Если приложение запускается через COM, оно может отключиться в последнем справочном выпуске COM. (Обычно это определяется с помощью дополнительного глобального счетчика ссылок, который увеличивается для любого объекта AddRef и уменьшается для любого объекта Release). Однако приложение не должно закрываться само по себе, если оно обнаружило, что пользователь взаимодействовал с его пользовательским интерфейсом. в таком случае отключение откладывается до тех пор, пока пользователь не закроет последний пользовательский интерфейс явным образом (чтобы упростить это обнаружение, приложение обычно не показывает свой пользовательский интерфейс, пока пользователь не попытается запустить его явно)

Если приложение было запущено пользователем и пользовательский интерфейс las закрыт, приложение должно проверить, имеются ли в нем какие-либо ссылки на COM-объекты. Если их нет, он может отключиться сам. Однако, если есть ссылки на COM, приложение должно скрыть пользовательский интерфейс, но продолжать работу, пока не будет выпущена последняя ссылка.

Если приложение достигло точки, в которой оно будет закрыто, оно должно отозвать все регистрации фабрики классов.

0 голосов
/ 16 февраля 2009

Вы распределяете свой код в проекте сервера ATL. См. Примеры на Образцы серверов ATL .

...