P/Invoke или C++ / CLI для обертывания библиотеки C

Имейте умеренный размер (40 нечетных функций) C API, который нужно назвать из проекта C#. Функции логически разбиваются для формирования нескольких классов, которые будут API, представленным остальной части проекта.

Там какие-либо объективные причины состоят в том, чтобы предпочесть P/Invoke или C++ / CLI для совместимости подо что API, с точки зрения устойчивости, пригодности для обслуживания, развертывания...?

Проблемы, о которых я мог думать, который мог бы быть, но не проблематичны:

  • C++ / CLI будет требовать отдельной сборки, классы P/Invoke могут быть в основном блоке. (Мы уже получили несколько блоков и будет C dlls так или иначе так не главная проблема).
  • Производительность не кажется, отличаются примечательные между этими двумя методами.

Проблемы, в которых я не уверен:

  • Моим чувством является C++/, CLI будет легче отладить, если будет inter-op проблема, действительно ли это верно?
  • Знакомство языка достаточно людей знает C# и C++, но знание деталей C++ / CLI более редко здесь.

Что-нибудь еще?

34
задан Ian G 1 April 2010 в 16:19
поделиться

6 ответов

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

C ++ / CLI - отличная технология, но IMHO его документация ограничена по сравнению с PInvoke для конкретных сценариев взаимодействия. У него также нет инфраструктуры инструментов для решений взаимодействия, которые есть у PInvoke. Добавление сборки C ++ / CLI для сценария, который можно решить с помощью PInvoke, кажется мне слишком дорогостоящим.

С другой стороны, если я работаю с большой библиотекой C ++, я немного больше рассматриваю C ++ / CLI. PInvoke не работает с C ++, и я должен добавить какой-то промежуточный уровень. Либо небольшой слой C, чтобы обернуть все вызовы функций C ++, либо библиотека C ++ / CLI, чтобы заполнить пробел. В этом случае C ++ / CLI мне кажется более естественным.

17
ответ дан 27 November 2019 в 17:11
поделиться

Здесь много хороших ответов - еще одна перспектива - это план для существующего C API. Аргументы в пользу использования PInvoke включают:

  • Вы необходимо иметь C API для совместимости с другими потребителями C
  • Вам необходимо сохранить код на C, поскольку он большой, а перенос слишком дорогостоящий

Аргументы в пользу использования C ++ / CLI включают:

  • вы хотите переместить как можно больше кода в CLR

В этом случае вы можете начать с C ++ / CLI, а затем все больше и больше переходить на C #

0
ответ дан 27 November 2019 в 17:11
поделиться

C ++ / CLI будет легче отлаживать, если у вас есть персонал, который знает, как отлаживать C ++. Если вы этого не сделаете, это может быть намного сложнее.

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

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

2
ответ дан 27 November 2019 в 17:11
поделиться

Думайте о P/Invoke как о вызове платформы, вы вызываете что-то вроде Win32 API, который очень дружелюбен к P/Invoke, или вам нужно обеспечить .NET привязку для неуправляемой библиотеки?

Поскольку обертка обычно очень тонкая, обертка C++/CLI не требует, чтобы вы знали C++/CLI. Все, что вам нужно знать, можно найти в спецификации языка, это обширная документация с большим количеством примеров. P/Invoke - это скорее приятная возможность для небольших существующих библиотек, но если интерфейс для вызова этой библиотеки изменится, вы столкнетесь с проблемой. В C++/CLI вы все еще можете иметь публичный управляемый интерфейс в вашем проекте C++/CLI, который открыт для управляемого кода, и таким образом легче справляться с изменениями в C API.

Если вы хотите избавиться от лишней DLL, вы всегда можете попробовать ILMerge, но я не уверен, что он способен работать со смешанными сборками (видимо, нет), но похоже, что можно соединить управляемые и неуправляемые *.obj файлы с помощью компоновщика PlatformSDK следующим образом:

cl.exe /MD /c /clr Unmanaged.cpp
csc.exe /target:module /addmodule:*.obj Managed.cs
link.exe /DLL /LTCG /NOENTRY /CLRIMAGETYPE:IJW *.obj Managed.netmodule
5
ответ дан 27 November 2019 в 17:11
поделиться

Для API такого размера (всего около 40 точек входа) я бы провел разделительную линию между C ++ / CLI и P / Invoke в зависимости от того, сколько у вас «мусора из файла заголовка». нужно продублировать на C #. Если это небольшая (или скромная) сумма, подойдет P / Invoke. Как только вы начнете дублировать множество файлов .H на C # - особенно для вещей, которые не представлены в вашем .NET API - вам может быть лучше использовать C ++ / CLI.

2
ответ дан 27 November 2019 в 17:11
поделиться

Это в значительной степени зависит от того, как обрабатывается владение памятью. P/invoke может маршалить указатели только тогда, когда управление памятью происходит одним из пары определенных способов, обычно это буферы, выделяемые вызывающей стороной. Если ваш API возвращает указатели (через возвращаемое значение или параметр out, неважно) и ожидает, что они будут переданы обратно в функцию уничтожения позже... p/invoke либо сделает автоматическое маршалинг, либо предоставит вам прямой доступ к значению указателя, которое вам нужно отправить обратно позже, но никогда и то, и другое. Так что C++/CLI становится очень желательным подходом в этом случае.

8
ответ дан 27 November 2019 в 17:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: