C# 中的DllImport用法详解

5星 · 超过95%的资源 需积分: 50 41 下载量 65 浏览量 更新于2024-09-17 收藏 7KB TXT 举报
"C# DllImport的用法" 在C#编程中,有时我们需要使用到已经存在于操作系统或者其他非托管库中的功能,例如Windows API或C++编译的库。为了能够直接调用这些非托管代码的功能,C#提供了`DllImport`特性。这个特性允许我们直接在C#程序中调用非托管DLL中的函数,无需重新实现。 `DllImport`特性位于`System.Runtime.InteropServices`命名空间下,它是用来装饰方法声明的,以便告诉.NET框架该方法是从非托管DLL中导入的。其基本语法如下: ```csharp [DllImport("dllName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)] extern void NativeFunction(); ``` 这里,`dllName`参数是必需的,用于指定包含导入函数的DLL的名称。其他如`CallingConvention`、`CharSet`、`EntryPoint`、`ExactSpelling`、`PreserveSig`和`SetLastError`等参数则是可选的,它们用于进一步定制导入过程。 1. `CallingConvention`:这个参数定义了调用约定,即函数参数如何在调用和被调用之间传递。常见的取值有`CallingConvention.Cdecl`(C语言调用约定)和`CallingConvention.StdCall`(标准调用约定,通常用于Windows API)。如果不指定,默认为`CallingConvention.Winapi`,它在x86平台上等同于`StdCall`,而在其他平台上等同于`Cdecl`。 2. `CharSet`:这个参数指定了在DLL中使用的字符集。例如,如果你知道DLL使用的是ANSI字符集,可以设置为`CharSet.Ansi`;如果使用Unicode字符集,设置为`CharSet.Unicode`。不指定的话,默认为`CharSet.Auto`,.NET会自动选择合适的字符集。 3. `EntryPoint`:这个参数用于指定DLL中函数的实际入口点名称。当DLL函数名称与C#方法名称不一致时,需要明确指定。如果不指定,将默认使用C#方法的名称。 4. `ExactSpelling`:这个属性表示是否需要精确匹配函数名称。如果设为`true`,则必须按原样提供函数名称,不允许.NET框架添加或删除任何字符。默认值是`false`,意味着.NET框架可以尝试根据C#方法签名来推断正确的名称。 5. `PreserveSig`:这个属性决定是否保持方法签名的原始状态。如果设为`true`(默认),签名将被保留,返回类型将不会被转换为`int`(代表HRESULT)。如果设为`false`,签名将会被修改,返回类型会变为`int`,并增加一个名为`retval`的输出参数。 6. `SetLastError`:这个属性控制是否在调用函数后检查Win32的“最后一个错误”。如果设为`true`,.NET将允许访问`Marshal.GetLastWin32Error()`获取错误信息。默认值是`false`,意味着不检查“最后一个错误”。 使用`DllImport`的注意事项: - 被`DllImport`修饰的方法必须使用`extern`关键字,因为它们是外部定义的,不在当前编译单元内实现。 - 调用的非托管函数必须与C#方法的签名兼容,包括参数类型和顺序。 `DllImport`是C#与非托管代码交互的关键工具,通过它可以灵活地调用各种非托管库中的函数,从而充分利用已有的功能和资源。正确理解和使用`DllImport`能够极大地扩展C#应用程序的能力。