2009-12-16 4 views
2

Я пытаюсь понять мои варианты вызова реализации библиотеки C# из неуправляемого C++.C++ COM C# Interoperation смешанного режима

Мой модуль верхнего уровня - это неуправляемая DLL C++ COM/ATL. Я хотел бы интегрировать функциональные возможности существующей управляемой C# dll. Я имею и могу перекомпилировать источник для обеих библиотек.

Насколько я понимаю из чтения статей, таких как this overview на MSDN и this SO question, возможно создание «смешанного режима» dll, которое позволяет использовать собственный C++-код в библиотеке C#.

У меня есть несколько вопросов об этом подходе:

  1. Как идти о создании это? Могу ли я просто изменить некоторые свойства на существующий проект COM/ATL на , разрешить использование модулей C#?
  2. Как эти смешанные вызовы отличаются производительностью от COM-взаимодействия звонки? Есть ли общая строка формат, который может использоваться для предотвращения преобразования между модулями?
  3. Если эта длл создается смешанного режима, это может все еще быть сопрягаемые/используется таким же образом, с помощью своих COM клиентов, или же они должны быть режим известно смешано?
  4. Включение CLR накладывает существенные накладные расходы при загрузке этого COM-объекта?

Я новичок в разработке Windows, поэтому, пожалуйста, прокомментируйте, если что-либо в формулировке вопроса нуждается в разъяснении или исправлении.

Заранее спасибо.

ответ

4

Как мне это настроить? Могу ли я просто изменить некоторые свойства в существующем проекте COM/ATL, чтобы разрешить использование модулей C#?

Если вы полностью контролируете этот проект, поэтому изменение таких настроек не является проблемой, а затем обязательно. Все, что вам нужно, это включить /clr для этого проекта (в свойствах проекта откройте страницу «Общие» и найдите поддержку «Common Language Runtime»). Теперь вы можете использовать управляемые ручки (^) и другие биты C++/CLI в своем проекте по мере необходимости.Весь существующий код, написанный на простом C++, должен просто продолжать работать (теперь он будет скомпилирован в MSIL, насколько это возможно, но его семантика останется без изменений).

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

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

Нет общего формата строк - проблема заключается в том, что System::String обе выделяет и владеет своим буфером, а также требует, чтобы он был неизменным; поэтому вы не можете создать буфер самостоятельно, а затем оберните его как String или создайте String, а затем используйте его в качестве буфера для вывода текста.

Если эта dll создана в смешанном режиме, может ли она по-прежнему быть сопряжена/использована аналогичным образом ее COM-клиентами или им нужно быть знакомым в смешанном режиме?

Это может быть сопряжено с одним и тем же, но если оно введено через собственную точку входа, оно попытается загрузить CLR в процесс, если только он не загружен. Если вызывающий клиент уже загрузил CLR до вызова (или сам клиент был вызван из управляемого кода), вы получите CLR, который уже загружен, который может отличаться от CLR, который требуется вашему коду (например, клиент может загрузиться 1.1, а вашему коду нужно 2.0).

Включает ли CLR существенные накладные расходы при загрузке этого COM-объекта?

Это зависит от того, что вы определяете по накладным расходам. Размер кода? Временные штрафы? Память?

В любом случае, погрузка CLR означает, что вы получаете все оборудование GC и JIT. Это не дешево. Тем не менее, если вам нужно вызвать управляемый код в любом случае, нет никакого способа обойти это - у вас будет , чтобы загрузить CLR в какой-то процесс, чтобы сделать это. Штрафы не будут отличаться между COM Interop и смешанными модулями C++/CLI.

+0

Спасибо за отличную информацию. Хотел бы я дать больше, чем один голос. –

+0

Очень предвзятое мнение. COM-вызовы не медленнее. Накладные расходы CLR являются существенными. – wqw

+0

Объясните, как вызов COM не будет медленнее, если он использует соглашение о вызове, которое требует нажатия всех аргументов в стек (без передачи в реестре), в то время как прямые управляемые вызовы C++/CLI с прямым управлением будут использовать «thiscall». Кроме того, при использовании '/ clr', большинство кодов будет скомпилировано в MSIL в первую очередь - как для классов' ref', так и для non -ref', поэтому для входа в DLL будет один управляемый переход на основе native-> оттуда все управляется, без штрафных санкций. Я сказал, что накладные расходы на CLR являются существенными, но как вы избегаете его с помощью COM-взаимодействия (или иначе)? –

0

Я не могу сказать много о деталях, например, например. проблемы с строкой, так как я никогда не использовал этот подход.

Но вы можете легко использовать любой COM-интерфейс из любого кода C#, просто предоставив мастер VS создать прокси-сервер для вас, для него нет служебных накладных расходов, кроме тех, которые вы всегда имеете при вызове COM и .NET.

В другом направлении вам просто нужно установить для своих сборщиков C# ComVisibleAttribute значение true (в VS это простой флажок в свойствах проекта), а затем компилятор автоматически создаст для вас COM-интерфейсы. Опять же, нет дополнительного штрафа за исполнение.

HTH!

+0

«нет дополнительного штрафа за исполнение» - дополнительно по сравнению с чем? –

+0

По сравнению с «для него нет служебных накладных расходов, кроме тех, которые вы всегда имеете при вызове COM и .NET», как я уже говорил несколько строк. Совет: Чтение помогает ... –

+0

Все еще не анализируется. «Нет дополнительного штрафа» относится к вызову .NET через COM (поскольку вы указываете создание прокси-серверов и т. Д., Это не подход «прямой родной/управляемый C++/CLI»). И теперь вы, по сути, говорите, что это означает «нет дополнительного штрафа при вызове .NET через COM, кроме штрафа, который есть». Это, безусловно, истинное утверждение, просто не очень информативное :) –

Смежные вопросы