Обертывание неуправляемого C ++ с C ++ / CLI - правильный подход - PullRequest
8 голосов
/ 10 января 2011

, как указано в заголовке, я хочу, чтобы моя старая библиотека C ++ работала в управляемом .NET. Я думаю о двух возможностях:

1) Я мог бы попытаться скомпилировать библиотеку с / clr и попробовать "It Just Works".

2) Я мог бы написать управляемую оболочку в неуправляемую библиотеку.

Прежде всего, я хочу, чтобы моя библиотека работала БЫСТРО, как это было в неуправляемой среде. Таким образом, я не уверен, что первый подход не приведет к значительному снижению производительности. Однако, это, кажется, быстрее реализовать (не правильное слово :-)) (при условии, что это будет работать для меня).

С другой стороны, я думаю о некоторых проблемах, которые могут возникнуть при написании оболочки (например, как обернуть некоторую коллекцию STL (например, vector)?), Я думаю о написании оболочки, находящейся в том же проекте, что и находится неуправляемый C ++ - это разумный подход (например, MyUnmanagedClass и MyManagedClass в одном проекте, второй - обертка другого)?

Что бы вы предложили в этой проблеме? Какое решение даст мне лучшую производительность полученного кода?

Заранее благодарю за любые предложения и подсказки!

Приветствия

Ответы [ 3 ]

6 голосов
/ 10 января 2011

Прежде всего, забудьте о Managed C ++.Используйте C ++ / CLI.

Разница в том, что Managed C ++ был первой попыткой Microsoft расширить C ++ для работы с .NET, и, честно говоря, это было ужасно.

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

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

Конечно, для того, чтобы представить ваши типы C ++ для сборок .NET, вам придется написать несколько оболочек в любом случае.Для типов STL вы можете заглянуть в библиотеку Microsoft STL / CLR .

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

3 голосов
/ 10 января 2011

То, как я это делаю, это

  1. Создать обычный неуправляемый .lib.Убедитесь, что вы ссылаетесь на стандартную среду выполнения в виде DLL (требуется, если .lib находится в сборке)

  2. Создание сборки C ++ / CLI.

  3. Добавить .lib к ссылке, аналогичной сборке

  4. Создать управляемый интерфейс

  5. Минимизируйте гранулярность вызовов через управляемые / неуправляемые.Это означает, что вы предпочитаете получать большие порции данных (например, структуру данных), а не использовать интерфейс с неуправляемой структурой данных с управляемой стороны.Это происходит потому, что вызовы через границу медленны.

Такие вещи, как std :: vector, должны быть упакованы вручную в System.Collections - но "это просто работает" - это хорошодля встроенных типов и даже указателей на функции.

Другие ошибки.Обратные вызовы должны быть stdcall, чтобы превратиться в делегата, а delgates, отправленные неуправляемым обратным вызовам, не содержат ссылку (поэтому, организуйте удерживать ссылку где-нибудь еще или произойдет сбой, когда объект GC'd).

1 голос
/ 10 января 2011

Если у вас много неуправляемых функций для переноса, вам следует рассмотреть возможность использования SWIG .Он пишет весь код оболочки и взаимодействия для вас, и имеет предварительно написанные файлы интерфейса SWIG, которые поддерживают std :: vector, std :: string, типы окон и т. Д.DLL функции, если вы заинтересованы.

...