Поделиться через


Использование собственных серверов COM в .NET

Обновлен: Ноябрь 2007

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

Использование средства TLBIMP

Средство Программа импорта библиотек типов (Tlbimp.exe) входит в SDK (пакет средств разработки программного обеспечения) для Windows и предоставляет библиотеку типов COM в виде сборки взаимодействия. В этой сборке определяются управляемые эквиваленты или оболочки для каждого интерфейса COM в указанной библиотеке типов.

При вызове метода из сборки взаимодействия выполняется преобразование из управляемого в неуправляемый код, после чего управление передается компоненту COM. Аналогичным образом при возвращении неуправляемой функции COM выполняется преобразование из неуправляемого в управляемый код. По умолчанию проверяется значение типа HRESULT COM на наличие ошибки. Если значение HRESULT не содержит кода успешного выполнения, вызывается исключение. Запросы интерфейса и инициализации компонентов COM также выполняются с помощью сборки взаимодействия и скрыты от вызывающего кода.

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

Средство Tlbimp предоставляет самый простой способ использования компонентов COM в управляемом коде, однако оно обладает рядом серьезных недостатков, связанных в основном с применением объемных и сложных интерфейсов COM. К этим недостаткам можно отнести:

  • Создание средством Tlbimp управляемых интерфейсов для каждого интерфейса COM, представленного в библиотеке типов. Отключить такое поведение нельзя, что может привести к созданию сборок большого размера. (Например, размер сборки взаимодействия, создаваемой средством Tlbimp для библиотеки Mshtml.dll, составляет более 8 МБ.) Также нельзя скрыть интерфейсы, предназначенные для использования только внутри компонента COM.

  • Поддержка средством Tlbimp ограниченного числа типов данных. Обычно неподдерживаемые типы импортируются в управляемый код с использованием не являющегося строго типизированным универсального типа IntPtr. В этом случае для использования сборки необходимо применять подверженный ошибкам и достаточно объемный код маршалинга, а в некоторых случаях члены интерфейса полностью не поддерживаются средством Tlbimp.exe.

  • Создание средством Tlbimp отдельной сборки взаимодействия, которая должна развертываться вместе с готовым приложением.

Если эти недостатки являются приемлемыми, ознакомьтесь с примером, представленным в разделе Практическое руководство. Использование неуправляемых COM-серверов с помощью средства TLBIMP.

Изменение кода MSIL

Чтобы в определенной степени устранить недостатки средства Tlbimp, можно дизассемблировать сборку взаимодействия. Для этого используется Дизассемблер MSIL (Ildasm.exe), который позволяет изменить код MSIL, удалить ненужные определения интерфейса и заменить типы аргументов, после чего выполнить повторное построение кода MSIL (используется Ассемблер MSIL (Ilasm.exe)). При выполнении этого процесса существует высокая вероятность ошибок, а также требуется знание языка MSIL, неуправляемых типов и типов .NET. Кроме того, в случае обновления интерфейсов COM требуется повторное выполнение этого процесса.

Взаимодействие C++

В Visual C++ можно полностью избежать недостатков, связанных с использованием средства Tlbimp или изменением кода MSIL. Это связано с тем, что в Visual C++, в отличие от Visual Basic и C#, поддерживается непосредственное использование объектов COM с помощью стандартных механизмов COM (например CoCreateInstance и QueryInterface). Для этого используются функции взаимодействия C++, с помощью которых при компиляции автоматически добавляется код преобразования из управляемых функций в неуправляемые и наоборот.

Благодаря взаимодействию C++ компоненты COM могут использоваться обычным способом или заключаться в классы C++. Такие классы-оболочки называются пользовательскими вызываемыми оболочками времени выполнения (CRCW) и обладают двумя преимуществами по отношению к непосредственному использованию объектов COM в коде приложения:

  • Результирующий класс может использоваться в языках, отличных от Visual C++.

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

Пример применения Visual C++ в качестве оболочки для интерфейсов COM см. в разделе Практическое руководство. Использование встроенных серверов COM с CRCW.

Независимо от того, используются ли объекты COM напрямую или с помощью классов, необходимо выполнять маршалирование типов аргументов, не являющихся простыми преобразуемыми типами. Дополнительные сведения о маршалинге данных см. в разделе Использование взаимодействия языка C++ (неявный PInvoke).

zeaxheha.alert_note(ru-ru,VS.90).gifПримечание.

Приложения MFC необходимо инициализировать в виде однопотокового подразделения (STA). Если метод CoInitializeEx вызывается в пользовательском переопределении метода InitInstance, необходимо указать в качестве значения параметра константу COINIT_APARTMENTTHREADED, а не COINIT_MULTITHREADED. Дополнительные сведения см. в статье "PRB. Приложение MFC не отвечает при инициализации приложения в виде многопотокового подразделения" (на английском языке, ИД статьи — 828643) по адресу https://support.microsoft.com/default.aspx?scid=kb;ru-ru;828643.

См. также

Другие ресурсы

Взаимодействие исходного кода и платформы.NET