Создание COM-расширения с использованием C # - оно того стоит? - PullRequest
2 голосов
/ 18 июня 2009

Я имею дело со следующей проблемой: (стороннее) программное обеспечение ( Программное обеспечение A ) мы широко используем программирование того, что он называет «расширениями», используя интерфейс COM (объектная модель компонентов) (фактически несколько интерфейсов). Он предоставляет файлы MIDL для этих интерфейсов, а также «шаблон проекта» для Visual C ++ как часть SDK (файлы IDL, заголовки и интерфейсы уже есть, отсутствуют только реализации для функций интерфейса). Чтобы быть совместимыми, все расширения должны соответствовать (т.е. должны реализовывать) заданной структуре интерфейса COM.

Однако, поскольку мое знакомство с C ++ довольно ограничено, я надеялся реализовать COM в C # и .NET - с другой стороны, предопределенные интерфейсы интенсивно используют указатели и пользовательские структуры данных, поэтому я интересно, не лучше ли мне реализовать интерфейсы в их родном C ++, а не пытаться воссоздать все в C #.

Может быть, немного больше предыстории: конечная цель - управлять частью пользовательского оборудования (через USB) изнутри Программного обеспечения A. Я уже написал небольшое приложение .NET, оборачивающее драйвер (другое стороннее программное обеспечение), используя DLLimport который был удивительно безболезненным. Другими словами, COM-объект, который я пытаюсь создать, по сути является мостом между (сторонним) программным обеспечением A и (сторонним) драйвером устройства B, который должен соответствовать спецификациям интерфейса, данным A.


образец MIDL-кода:

[id (0x00000004)]
HRESULT GetWaveData ([in] имя BSTR, [out] IWaveData ** data);
[id (0x00000005)]
HRESULT GetImageData ([in] имя BSTR, [out] IImageData ** data, [out] палитра * палитра);
[id (0x00000006)]
HRESULT SetVariable ([in] имя BSTR, [in] переменная IVariableData *);

Ответы [ 4 ]

5 голосов
/ 18 июня 2009

На самом деле невозможно ответить на этот вопрос, не зная проблемы полностью. Но в целом, я бы пошел с маршрутом C ++. Добавив CLR в мир, вы будете иметь дело с проблемами взаимодействия и, возможно, справляться с неприятными проблемами с указателями (поскольку по своей природе это касается низкоуровневых аппаратных средств) в C #. В результате, вероятно, ваш реальный выбор - нечистый источник C # или переход на C ++. Я думаю, я бы выбрал последнее.

2 голосов
/ 18 июня 2009

Технически, вы реализуете не интерфейсы в C ++, а MIDL. Это отдельный язык интерфейса, и его стоит знать, если вы собираетесь работать с COM.

В любом случае, для реализации COM-объектов весьма обычно использовать взаимодействия .NET, но эти две технологии не являются действительно совместимыми. Вы столкнетесь с ошибками, если не будете писать очень простые объекты.

Для начала, вот несколько случайных указателей вместе с парой статей, которые я использовал в прошлом.

  • COM - это технология, управляемая интерфейсом. Повторите это снова и снова.
  • Разрабатывайте определение интерфейса отдельно, используя MIDL.
  • Сборка мусора COM является детерминированной (подсчет ссылок), но она начинает разваливаться при использовании с .NET, где сборка мусора происходит автоматически и непредсказуемо.
  • Работа с Eventinks / обработчиками событий ужасна.

Небольшой вкус типа головных болей, с которыми вы столкнетесь: http://www.codeproject.com/KB/cs/LingeringCOMObjects.aspx

Подробнее о том, почему вы НЕ должны позволять Visual Studio автоматически генерировать COM-интерфейс для вас: http://blogs.msdn.com/mbend/archive/2007/04/17/classinterfacetype-none-is-my-recommended-option-over-autodispatch-autodual.aspx

Связывание событий: http://www.west -wind.com / презентации / dotnetfromVfp / DotNetFromVfp_EventHandling.asp

1 голос
/ 18 июня 2009

Похоже, решение, которое вы принимаете, зависит от того, хотите ли вы использовать нативное приложение или приложение на основе .NET.

Вам нужно подумать о следующем:

  1. Проблемы развертывания : где вы собираетесь развернуть это приложение? Это что-то, что будет работать на сотнях рабочих станций или просто на паре? Какой контроль вы будете иметь над машинами, на которых он установлен? Помните, что вам нужно убедиться, что установлена ​​правильная версия платформы .NET;

  2. Проблемы с обслуживанием : вы явно более знакомы с .NET, но кто будет заботиться о приложении в долгосрочной перспективе? Предполагается ли, что они будут знакомы с C ++? Нативное развитие на самом деле отличается от добытой рыбы, поскольку «домашнее хозяйство» является очень важной частью;

  3. Сторонние зависимости : мне кажется, что вы пытаетесь использовать стороннюю библиотеку COM для связи с вашим устройством через USB. Тем не менее, вы упомянули, что вы написали .NET-оболочку для драйвера оборудования - можете ли вы уточнить, так как это немного сбивает с толку. Если возможно, и если не слишком много хлопот, не вводите зависимости;

  4. Ресурсные ограничения : если ваше приложение будет установлено «в дикой природе», каковы ограничения аппаратного обеспечения? Программирование с использованием неуправляемой среды позволяет вам детально контролировать, сколько памяти будет использовать ваше приложение, и насколько оно сильно загружено - это, конечно, компромисс с наличием управляемого уровня, который заботится об управлении ресурсами .

В целом, если вы разрабатываете приложение, в котором нет необходимости развертывать тысячи пользователей с разнородными аппаратными конфигурациями, я бы выбрал платформу .NET. COM-взаимодействие в .NET относительно безболезненно, а программирование на управляемой платформе означает, что вы можете сосредоточиться на том, что важно. Если вы никогда ранее не программировали в неуправляемой среде (C / C ++), вас ждет шок.

1 голос
/ 18 июня 2009

Вы должны использовать .NET только для этой цели, если это дает вам преимущества. Например, когда-то нам требовался запуск веб-сервисов, и поддержка в .NET стала намного лучше, поэтому мы пошли по этому пути. В вашем случае преимущество заключается в том, что вы лучше знакомы с .NET, и это, возможно, стоит выбрать.

Однако, если вы реализуете COM-объект в .NET, вам понадобится среда выполнения .NET для каждой машины, на которой этот объект будет использоваться. Кроме того, у вас могут возникнуть проблемы с реализацией интерфейсов, в которых пользовательские типы трудно маршалировать.

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

Мое личное мнение заключается в том, что путь .NET следует выбирать только в том случае, если там требуется доступная функциональность (например, вызов веб-сервисов).

...