在C#中,`DllImport` 属性用于从非托管代码(如C或C++编写的DLL)中导入函数。这通常用于调用系统API或第三方库中的函数。以下是`DllImport`的详细使用方法:
### 1. 引入命名空间
首先,你需要在文件顶部引入`System.Runtime.InteropServices`命名空间,因为它包含了`DllImport`属性。
using System.Runtime.InteropServices;
### 2. 定义`DllImport`属性
然后,你可以在你的类中定义一个方法,并使用`DllImport`属性来指定该方法在DLL中的名称。这个属性需要指定DLL的名称(不包括`.dll`扩展名,除非DLL在非标准位置)。
public class NativeMethods
{
// 假设DLL名为"ExampleLib.dll",并且里面有一个名为"MyFunction"的函数
[DllImport("ExampleLib", CallingConvention = CallingConvention.Cdecl)]
public static extern void MyFunction();
}
### 3. 设置调用约定
`DllImport`属性中的`CallingConvention`参数是可选的,但它非常重要,因为它定义了托管代码和非托管代码之间的调用方式。最常见的调用约定是`Cdecl`和`StdCall`。你需要根据DLL中函数的实际调用约定来设置这个参数。
### 4. 调用非托管函数
一旦你定义了带有`DllImport`属性的方法,你就可以像调用任何其他静态方法一样调用它了。
NativeMethods.MyFunction();
### 5. 处理参数和返回值
如果你的非托管函数有参数或返回值,你需要在C#方法声明中相应地声明它们。确保参数和返回值的类型与DLL中函数的参数和返回值的类型相匹配(或至少兼容)。
[DllImport("ExampleLib", CallingConvention = CallingConvention.Cdecl)]
public static extern int MyFunctionWithArgs(int arg1, string arg2);
// 调用
int result = NativeMethods.MyFunctionWithArgs(1, "Hello");
### 6. 错误处理
调用非托管代码时,错误处理可能比较复杂。通常,你需要检查非托管函数提供的返回值或输出参数来检测错误。有时,你可能还需要设置`SetLastError`为`true`(在`DllImport`属性中),并在调用后使用`Marshal.GetLastWin32Error`来获取最后的错误代码。
[DllImport("ExampleLib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern bool MyFunctionThatCanFail();
// 调用并检查错误
if (!NativeMethods.MyFunctionThatCanFail())
{
int errorCode = Marshal.GetLastWin32Error();
// 处理错误
}
以上就是在C#中使用`DllImport`属性调用非托管DLL函数的基本方法。