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

2

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

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

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


пример кода MIDL:

[id (0x00000004)]
HRESULT GetWaveData ([in] BSTR name, [out] IWaveData ** данные);
[id (0x00000005)]
HRESULT GetImageData ([in] BSTR name, [out] данные IImageData **, [out] Palette * Palette);
[id (0x00000006)]
HRESULT SetVariable ([in] BSTR name, [in] переменная IVariableData *);
Теги:
com
interop

4 ответа

5

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

2

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

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

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

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

Небольшой вкус типа головных болей, с которыми вы столкнетесь: 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/presentations/dotnetfromVfp/DotNetFromVfp_EventHandling.asp

  • 0
    +1 Специально для маркера Eventsinks. Это было огромной проблемой для меня в прошлом.
  • 0
    Спасибо за ссылки! Определение MIDL уже существует - в этом и заключается проблема: как я могу перевести определение интерфейса MIDL в .NET, поскольку, насколько я понимаю, представление COM-библиотек .NET не связано с MIDL (я ошибаюсь?) События, к счастью, не являются проблемой , Все COM - это явные вызовы функций типа set / get. Так что это, вероятно, довольно простой объект.
Показать ещё 1 комментарий
1

Похоже, что решение, которое вы принимаете, - это вопрос, нужно ли использовать собственное приложение или приложение на основе .NET.

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

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

  • Проблемы с обслуживанием: вы явно знакомы с .NET, но кто будет следить за приложением в долгосрочной перспективе? Ожидается ли, что они будут знакомы с С++? Естественное развитие на самом деле представляет собой различный чайник рыбы из управляемого развития, поскольку "домашнее хозяйство" является очень важной его частью;

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

  • Ограничения ресурсов: если ваше приложение будет установлено "в диком", каковы ограничения на аппаратное обеспечение? Программирование с использованием неуправляемой среды позволяет осуществлять мелкомасштабный контроль над тем, сколько памяти будет использовать ваше приложение, и как интенсивное использование ЦП - это, конечно же, компромисс против того, чтобы управляемый слой заботился об этом управлении ресурсами.

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

  • 0
    Спасибо за ответ! Я отредактировал свой оригинальный вопрос, чтобы сделать вещи немного яснее. Как вы правильно подозревали, развертывание не является проблемой и не является ограничением ресурсов, поэтому я бы предпочел не вдаваться в неуправляемый код.
1

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню