Смешивание кода C# и управляемого кода C++ в Windows с Visual Studio

Я хотел бы вызвать мои неуправляемые библиотеки C++ из моего кода C#. Каковы потенциальные ловушки и меры предосторожности, которые необходимо принять? Спасибо, что уделили мне время.

8 ответов


этот вопрос слишком широк. Единственный разумный ответ-P / Invoke, но это похоже на то, что если вы хотите программировать для Windows, вам нужно знать Win32 API.

почти целые книги были написаны о P / Invoke (http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X), и, конечно, целые веб-сайты были сделаны:http://www.pinvoke.net/.


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

другой маршрут - это реализация COM-классов umnanaged C++ и использование C# через автогенерированную сборку взаимодействия. Этот способ проще, если вы знаете свой путь вокруг COM достаточно хорошо.

надеюсь, что это помогает.


вы описываете P / Invoke. Это означает, что ваша библиотека C++ должна будет выставлять себя через интерфейс DLL, и интерфейс должен быть достаточно простым, чтобы описать P/Invoke через атрибуты вызова. Когда управляемый код вызывает в неуправляемый мир, параметры должны быть маршалированы, поэтому кажется, что может быть небольшое снижение производительности, но вам придется провести некоторое тестирование, чтобы увидеть, является ли маршалинг значительным или нет.


самый простой способ начать-убедиться, что все функции C++ представлены как функции стиля "C". Обязательно объявите функцию как _stdcall.

extern " C " _ _ declspec(dllexport) int _stdcall Foo (int a)

убедитесь, что вы получаете право маршалинга, особенно такие вещи, как указатели & wchar_t *. Если вы ошибаетесь, это может быть трудно отладить.

отлаживайте его с обеих сторон,но не с обеих. При отладке mixed native & managed, отладчик может работать очень медленно. Отладка 1 стороны одновременно экономит много времени.

получение более конкретного потребует более конкретного вопроса.


вы также можете вызвать неуправляемый код через P / Invoke. Это может быть проще, если ваш код в настоящее время не использует COM. Я думаю, вам, вероятно, нужно будет написать некоторые конкретные точки экспорта в вашем коде, используя привязки "C", если вы пошли по этому маршруту.

вероятно, самое большое, что вам нужно остерегаться в моем опыте, это то, что отсутствие детерминированной сборки мусора означает, что ваши деструкторы не будут работать, когда вы могли бы подумать, что они будут раньше. Нужно иметь имейте это в виду и используйте IDisposable или какой-либо другой метод, чтобы убедиться, что ваш управляемый код очищен, когда вы этого хотите.


конечно, всегда есть PInvoke, если вы упаковали свой код как DLL с внешними entrypoints. Ни один из вариантов не свободен от боли. Они зависят либо от А) вашего мастерства в написании COM, либо от управляемых c-оболочек b) рискуя рукой в PInvoke.


Я бы посмотрел на глоток, мы используем это для хорошего влияния на наш проект, чтобы предоставить наш API C++ другим языковым платформам.

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


Если вам нужны хорошие примеры PInvoke, вы можете посмотреть наPInvoke.net. Он имеет примеры того, как вызвать большинство функций win api.

также вы можете использовать утилиту из этой статьи Clr Наизнанку: PInvoke это переведет ваш .H файл в обертки c#.