在托管代码中创建原型
本主题将说明如何访问非托管函数,并介绍几种在托管代码中批注方法定义的特性字段。 有关说明如何构造用于平台调用的基于 .NET 的声明的示例,请参见用平台调用封送数据。
从托管代码中访问非托管 DLL 函数之前,首先需要知道该函数的名称以及将其导出的 DLL 的名称。 获取以上信息后,就可以开始为在 DLL 中实现的非托管函数编写托管定义。 此外,您还可以调整平台调用创建函数以及向/从函数封送数据的方式。
注意 |
---|
通过用于分配字符串的 Win32 API 函数,可以使用 LocalFree 等方法来释放字符串。平台调用将以不同的方式处理这些参数。对于平台 invoke 调用,应让参数为 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,该值对应于基于 32 位 Intel 的平台的 __stdcall。 |
|
控制名称重整以及将字符串参数封送到函数中的方式。 默认值为 CharSet.Ansi。 |
|
指定要调用的 DLL 入口点。 |
|
控制是否应修改入口点以对应于字符集。 对于不同的编程语言,默认值将有所不同。 |
|
控制托管方法签名是否应转换成返回 HRESULT 并且返回值有一个附加的 [out, retval] 参数的非托管签名。 默认值为 true(不应转换签名)。 |
|
允许调用方使用 Marshal.GetLastWin32Error API 函数来确定执行该方法时是否发生了错误。 在 Visual Basic 中,默认值为 true;在 C# 和 C++ 中,默认值为 false。 |
|
控制对转换为 ANSI“?”字符的不可映射的 Unicode 字符引发异常。 |
有关详细参考信息,请参见 DllImportAttribute 类。