Как использовать библиотеку C ++ из C # и .NET? - PullRequest
5 голосов
/ 27 августа 2010

Мой вопрос тесно связан с тем, как DLL экспортирует классы C ++ и универсальные методы (по сравнению с возможностями языка C ++ без параллели C #).

Я считаю, что вы можете вызывать функции внутри блока extern "C" из C #, просто ссылаясь на DLL и используя DLLImport.Но можете ли вы создать шаблонный тип C ++?Что если тип C ++ делает что-то сумасшедшее , которое не поддерживается в C #?Есть ли RFC или соответствующая часть спецификации C # ?

Спасибо ...

РЕДАКТИРОВАТЬ: Я наткнулся на P / Invoke , который должен быть ценным, но я все еще ищу спецификации или стандарта в этом отношении.

Ответы [ 3 ]

7 голосов
/ 27 августа 2010

Разумный способ сделать это - использовать управляемый c ++ для доступа к неуправляемому c ++ и компилировать в сборку.

2 голосов
/ 27 августа 2010

Я полагаю, что вы можете вызывать функции внутри внешнего блока "C" из C #, просто ссылаясь на DLL.

Неправильно, вы должны использовать DllImport или так называемый PInvoke (Platform Invoke) для вызова собственной функции C из управляемого кода.Ссылка работает только для сборок .NET или COM с автоматически созданным взаимодействием dll .

Использование C ++ из C # становится настоящим кошмаром из-за искажения имени среди других вещей.

Если вы можете, вы можете скомпилировать управляемый C ++ Dll как оболочку, чтобы оба мира встретились.Это также имеет то преимущество, что вы можете пометить вашу сборку как ComVisible, что делает ее доступной для множества инструментов, способных обрабатывать COM.

Альтернативой является написание оболочки C вокругAPI C ++, что может быть утомительным и уродливым.

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

Помогите решить, какой подход использовать:

  • 1) У вас есть родной C dll
    • ВНИМАНИЕ: если вы используете .lib из Managed C ++, тогда dll не является действительно динамически связанным и не может быть заменен простым добавлением более новой совместимой версии.
    • ПРЕДПОЧТИТЕЛЬНО: ИспользуйтеP / Invoke с любого языка .NET (возможна замена)

  • 2) У вас естьродной C ++ dll
    • НЕ используйте P / Invoke, это настоящий кошмар (из-за искажения имени среди прочего)
    • ПРЕДПОЧТИТЕЛЬНО: сборка оболочки .NET dll с управляемым C ++, работает толькоесли у вас есть компилятор, совместимый с тем, который использовался для компиляции нативной библиотеки DLL.
    • Если нативная DLL была собрана с несовместимым компилятором (компилятор A), который вы можете использовать для управляемого C ++ (компилятор C), то я советую собрать (с тем же компилятором A) обертку Cвокруг родной C ++ dll.Затем используйте метод P / Invoke для использования этой оболочки Cll, как описано в 1)
1 голос
/ 27 августа 2010

То, что DLL делает внутри, не имеет значения, если речь идет о C #. Имейте в виду, что шаблоны C ++ не генерируют никакого кода, пока не будет создан экземпляр шаблона. Если шаблон просто определен где-то в заголовочных файлах DLL, то не будет никакого сгенерированного кода для этого шаблона в DLL. С другой стороны, если DLL явно создает и экспортирует некоторые шаблонные типы, то вы можете теоретически вызывать их из C #.

Есть две проблемы, которые вам нужно преодолеть. Во-первых, компиляторы C ++ манипулируют именами своих методов, поэтому вам нужно точно определить, какое имя PInvoke является правильным. Вторая проблема заключается в том, что нет возможности создавать объекты CRT непосредственно в C #. Вам нужно будет определить некоторые фабричные методы и экспортировать их.

Честно говоря, я думаю, что это намного больше проблем, чем стоит. Вам лучше создать API в стиле C для DLL и вызывать эти функции из C #. Внутри функции могут создавать и управлять соответствующими объектами C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...