RTD — преобразование примера COM DLL в COM-exe

StackOverflow https://stackoverflow.com/questions/548551

  •  23-08-2019
  •  | 
  •  

Вопрос

Я планирую превратить существующее приложение в 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.

РЕДАКТИРОВАТЬ:

Обратите внимание: существующее приложение имеет графический интерфейс MFC.

РЕДАКТИРОВАТЬ:

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

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

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

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

Редактировать, что я начал награду по этому поводу, чтобы я мог получить образцы кода.Видимо, я слишком ленив и глуп (или, может быть, это просто гиперотвращение к COM), чтобы начать с существующего ответа Франси Пенова.(что очень полезно и отличное начало)

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

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

Все это сотворение, СоЭто и То и т. д.Где мне поместить этот код в мой exe?Как мне расширить/реализовать возможности IRTD?

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

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

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

Спасибо.

Это было полезно?

Решение

РЕДАКТИРОВАТЬ: Чувак, я не трогал 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 вне производства, вы можете посмотреть ЛАБРАДОР.

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

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

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

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

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

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

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

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

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

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

Другие советы

Вы маршалируете свой код в проекте ATL Server.Посмотрите образцы на Примеры серверов ATL .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top