Введение

Службы вызова платформы, обычно называемые P/Invoke, — это функция реализаций Common Language Infrastructure, таких как Common Language Runtime от Microsoft, которая позволяет управляемому коду вызывать нативный код. Управляемый код, такой как C# или VB.NET, обеспечивает нативный доступ к классам, методам и типам, определенным в библиотеках, составляющих .NET Framework. Хотя .NET Framework предоставляет обширный набор функциональных возможностей, ему может не хватать доступа ко многим библиотекам операционной системы более низкого уровня, обычно написанным на неуправляемом коде, или к библиотекам сторонних разработчиков, также написанным на неуправляемом коде. P/Invoke — это метод, который программист может использовать для доступа к функциям в этих библиотеках. Вызовы функций в этих библиотеках осуществляются путем объявления сигнатуры неуправляемой функции в управляемом коде, которая служит фактической функцией, которую можно вызвать, как и любой другой управляемый метод. Объявление ссылается на путь к файлу библиотеки и определяет параметры функции и возвращаемое значение в управляемых типах, которые, скорее всего, будут неявно преобразованы в неуправляемые типы и из них средой выполнения общего языка (CLR). Когда неуправляемые типы данных становятся слишком сложными для простого неявного преобразования в управляемые типы и обратно, среда позволяет пользователю определять атрибуты для функции, возвращаемого значения и/или параметров, чтобы явно уточнить, как данные должны быть преобразованы, чтобы избежать исключений при попытке сделать это неявно. По сравнению с программированием на неуправляемых языках, программистам управляемого кода доступны многочисленные абстракции концепций программирования более низкого уровня. В результате программисту, имеющему опыт только с управляемым кодом, потребуется вспомнить концепции программирования, такие как указатели, структуры и передача по ссылке, чтобы преодолеть некоторые трудности при использовании P/Invoke.

Неявный

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

Подробности

При использовании P/Invoke, CLR обеспечивает загрузку DLL и преобразование неуправляемых типов в типы CTS (также известное как маршаллинг параметров). Для этого CLR:
Находит DLL, содержащую функцию. Загружает DLL в память. Определяет адрес функции в памяти и помещает её аргументы в стек, выполняя маршаллинг данных по мере необходимости. P/Invoke полезен для работы со стандартными (неуправляемыми) DLL-файлами, написанными на C или C++. Он может быть использован, когда программисту требуется доступ к обширному API Windows, так как многие функции, предоставляемые библиотеками Windows, не имеют готовых обёрток. Если Win32 API не представлен в .NET Framework, обёртку для этого API необходимо создавать вручную.

PInvoke.net

PInvoke.net — это вики, содержащая сигнатуры P/Invoke для большого числа стандартных API Windows. Она принадлежит компании Redgate Software и насчитывает около 50 000 посещений в месяц. Сигнатуры создаются пользователями вики вручную. Их можно искать с помощью бесплатного расширения для Microsoft Visual Studio.

Пинвокер

PInvoker – это приложение, которое импортирует нативные DLL и h-файлы C++ и экспортирует полностью сформированные и скомпилированные P/Invoke interop DLL. Оно решает проблему неоднозначности, оборачивая параметры функций-указателей в классы интерфейсов .NET, специфичные для PInvoker. Вместо использования стандартных типов параметров .NET (int, string и т.д.) в определениях методов P/Invoke, оно использует эти классы интерфейсов при вызовах функций P/Invoke. Например, если рассмотреть вышеуказанный пример кода, PInvoker создаст функцию P/Invoke .NET, принимающую класс интерфейса .NET, оборачивающий нативный указатель. Этот класс может быть сконструирован из одиночного значения или из массива. Фактическая структура памяти для обоих случаев одинакова, но конструкторы соответствующих классов интерфейсов для каждого типа заполняют память по-разному. Таким образом, ответственность за выбор типа .NET, который необходимо передать в функцию, ложится на разработчика.

P/Invocate Wizard (Волшебник по вызову)

Мастер P/Invoke использует аналогичный метод, как и Microsoft Interop Assistant: он принимает код из заголовочных файлов C++ (.h) и генерирует код на C# (или VB.NET) для вставки в ваш код приложения .NET. Также предусмотрены параметры выбора целевой платформы: .NET Framework для настольных компьютеров или .NET Compact Framework для мобильных устройств Windows Mobile (и Windows CE).

xInterop C++ .NET Мост

xInterop C++ NET Bridge – это приложение для Windows, предназначенное для создания C#-оберток для нативных C++ DLL и C++-моста для доступа к .NET-сборкам. Оно поставляется с C#/.NET-библиотекой, которая оборачивает стандартные классы C++, такие как string, iostream и другие. Классы и объекты C++ могут быть доступны из .NET. Этот инструмент генерирует C#-обертки DLL с исходным кодом из существующих нативных C++ DLL и связанных файлов заголовков, необходимых для построения C#-обертки DLL. Приложение генерирует сигнатуры P/Invoke и выполняет преобразование данных. Полученная C#-обертка имеет интерфейс, аналогичный соответствующему C++-аналогу, с преобразованием типов параметров в .NET-код. Этот инструмент распознает классы-шаблоны, которые не экспортируются из C++ DLL, создает их экземпляр и экспортирует в дополнительную DLL, а соответствующий интерфейс C++ может быть использован в .NET.