С++ и С#: P/Invoke vs С++/CLI

В ходе поиска способа взаимодействия между С# и С++ я нашел эту статью которая объясняет P/Invoke.

И я прочитал много статей, утверждая, что С++/CLI не является точным С++ и требует некоторых усилий для изменения исходного кода на С++.

Я хочу спросить, что было бы оптимальным способом, когда у меня есть некоторые объекты С++ (код/​​данные), которые я хочу использовать из объектов С#.

  • Похоже, что для использования P/Invoke я должен предоставить API стиля C. Это правда? Я имею в виду, есть ли способ экспортировать объект С++ в С#, например, SWIG с P/Invoke? Или мне нужно использовать SWIG для этой цели?
  • Насколько сложно сменить С++ на С++/CLI? Стоит ли пытаться переписать С++ на С#? С++ хорошо разработан, поэтому реализовать его на С# не так уж много.
  • (С вопросом темы) Есть ли другой способ? Я имею в виду, если я хочу использовать код С# из С++, есть ли способ сделать это?

Ответ 1

Я бы не рекомендовал переписывать вашу С++-библиотеку в С++/CLI. Вместо этого я бы написал оболочку С++/CLI, которую вы можете вызывать из С#. Это будет состоять из некоторых классов public ref class, каждый из которых, вероятно, просто управляет экземпляром родного класса. Ваша оболочка С++/CLI просто "включает заголовок, ссылку на lib" для использования родной библиотеки. Поскольку вы написали классы public ref class, ваш код на С# просто добавляет ссылку .NET. И все, что вы делаете внутри каждого публичного класса ref, - это использование С++ Interop (aka It Just Works interop) для вызова собственного кода. Вы можете применить фасад, если хотите, если хотите.

Ответ 2

Синтаксис С++/CLI неудобен, но он позволяет вам выставлять управляемые объекты из кода С++. Это может быть удобно, если у вас есть большой С++ API и можно абстрагировать некоторые из этих функций на более простой интерфейс для использования вашим управляемым кодом. Я сделал это успешно для интеграции с такими инструментами, как библиотека видения Matrox, где я мог написать код анализа видения на С++, а затем использовать расширения С++/CLI для отображения управляемых классов высокого уровня. Самой болезненной частью, вероятно, является взаимодействие между строками и массивами, но строки всегда были болезненными даже на простом С++.

С++/CLI может определенно потреблять любые управляемые объекты .NET, но вам нужно проявлять особую осторожность, если вы используете какие-либо указатели на управляемую память (в этом случае вам нужно использовать пиннинг.) Если мне нужно пройти указатели на API, я обычно предпочитаю держать эту память неуправляемой, а затем создавать классы управляемых оболочек для управления неуправляемой памятью.

Ответ 3

В дополнение к ответу Кейт Грегори, чтобы вызвать код С# из С++, использование С++/CLI - это очевидный способ сделать это, поскольку он делает его чрезвычайно простым и бесшовным.

Ответ 4

Оберните свои родные классы С++, как указатель на реализацию, в классы С++/CLI, затем вызовите и используйте эти классы на основе CLR, "используя" их в своем приложении .net. Это мой рекомендуемый способ. НЕ ОБНОВЛЯЙТЕ существующие классы в С++/CLI.