Создание прототипов в управляемом коде
В этом разделе описывается порядок обращения к неуправляемым функциям и представлено несколько полей атрибутов, которые уточняют определение метода в управляемом коде. Примеры, в которых показывается способ создания объявлений на основе .NET, предназначенных для использования с вызовом неуправляемого кода, см. в разделе Маршалинг данных с вызовом неуправляемого кода.
Чтобы можно было обратиться к неуправляемой функции DLL из управляемого программного кода, требуется знать имя функции и имя библиотеки DLL, которая ее экспортирует. Располагая этими сведениями, разработчик может приступить к созданию управляемого определения для неуправляемой функции, реализованной в DLL. Кроме этого, можно настроить порядок создания функции при вызове неуправляемого кода, а также маршалинг данных в функцию и обратно.
Примечание |
---|
Функции Win32 API, которые распределяют строку, позволяют освободить строку с помощью, например, метода LocalFree.При вызове неуправляемого кода эти параметры обрабатываются иначе.Для вызовов неуправляемого кода следует использовать параметр типа IntPtr, а не типа String.Чтобы вручную преобразовать тип в строку и вручную освободить его, можно использовать методы, предоставленные классом System.Runtime.InteropServices.Marshal. |
Основы объявления
Как показано в следующих примерах, управляемые определения неуправляемых функций зависят от используемого языка. Более полные примеры кода см. в разделе Примеры вызовов неуправляемого кода.
Imports System.Runtime.InteropServices
Public Class Win32
Declare Auto Function MessageBox Lib "user32.dll" _
(ByVal hWnd As Integer, _
ByVal txt As String, ByVal caption As String, _
ByVal Typ As Integer) As IntPtr
End Class
Чтобы применить в объявлении Microsoft Visual Basic 2005 поля BestFitMapping, CallingConvention, ExactSpelling, PreserveSig, SetLastError или ThrowOnUnmappableChar, необходимо использовать атрибут DllImportAttribute вместо инструкции Declare.
Imports System.Runtime.InteropServices
Public Class Win32
<DllImport ("user32.dll", CharSet := CharSet.Auto)> _
Public Shared Function MessageBox (ByVal hWnd As Integer, _
ByVal txt As String, ByVal caption As String, _
ByVal Typ As Integer) As IntPtr
End Function
End Class
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
public static extern IntPtr MessageBox(int hWnd, String text,
String caption, uint type);
using namespace System::Runtime::InteropServices;
[DllImport("user32.dll")]
extern "C" IntPtr MessageBox(int hWnd, String* pText,
String* pCaption unsigned int uType);
Настройка определения
Значения атрибутов, заданные явно или неявно, определяют выполнение управляемого программного кода. Вызов неуправляемого кода выполняется работает в соответствии с набором стандартных значений различных полей, хранящихся в сборке как метаданные. Подстраивая значения одного или нескольких полей, можно изменить это поведение по умолчанию. Во многих случаях для установки значения используется DllImportAttribute.
В следующей таблице представлен полный набор полей атрибутов, имеющих отношение к вызову неуправляемого кода. Для каждого поля в таблице имеется стандартное значение и ссылка на сведения об использовании этих полей для определения неуправляемых функций DLL.
Поле |
Описание |
---|---|
Включает и отключает наилучшее сопоставление. |
|
Задает соглашение о вызовах, которое должно использоваться при передаче аргументов методов. По умолчанию используется значение WinAPI, соответствующее режиму __stdcall для 32-разрядных платформ на основе процессора Intel. |
|
Управляет изменением имен при передаче и задает способ маршалинга строковых аргументов в функцию. По умолчанию используется CharSet.Ansi. |
|
Задает точку входа DLL для вызова. |
|
Определяет, должна ли изменяться точка входа в соответствии с кодировкой. Значение зависит от языка программирования. |
|
Определяет, должна ли управляемая сигнатура метода преобразоваться в неуправляемую сигнатуру, которая возвращает значение HRESULT и для возвращаемого значения имеет дополнительный аргумент [out, retval]. По умолчанию используется значение true (сигнатура не должна преобразовываться). |
|
Позволяет вызывающему объекту при выполнении метода для определения факта ошибки использовать функцию интерфейса API Marshal.GetLastWin32Error. В Visual Basic по умолчанию используется значение true, в C# и C++ — значение false. |
|
Управляет возникновением исключения при появлении несопоставимого символа Юникода, который преобразуется в символ ANSI "?". |
Подробную справочную информацию см. в разделе Класс DllImportAttribute.
См. также
Основные понятия
Использование неуправляемых функций DLL
Примеры вызовов неуправляемого кода
Вопросы безопасности при вызове неуправляемого кода
Идентификация функций в библиотеках DLL
Создание класса, содержащего функции DLL