C#中DllImport的详细使用教程

版权申诉
5星 · 超过95%的资源 1 下载量 109 浏览量 更新于2024-07-06 收藏 19KB DOCX 举报
"C#中使用DllImport调用非托管DLL的详细指南" 在.NET框架中,C#不直接支持调用非托管代码,如C++、Delphi等编译的动态链接库(DLL)。为了实现这种跨语言互操作性,C#引入了`DllImport`属性。`DllImport`是`System.Runtime.InteropServices`命名空间下的一个特性类,它的主要作用是提供从非托管DLL导入函数所需的信息。 DllImport的定义包含以下几个关键部分: 1. **DllName**: 这是必须提供的参数,用于指定包含目标函数的DLL文件名。例如,`[DllImport("kernel32")]`指定了我们要调用的函数来自名为"kernel32.dll"的系统库。 2. **CallingConvention**: 指定函数调用约定,如`StdCall`、`Cdecl`等。默认是`StdCall`,适用于大多数Windows API函数。 3. **CharSet**: 指定字符集,如`Ansi`、`Unicode`或`Auto`。这影响到字符串参数的处理方式。 4. **EntryPoint**: 如果DLL函数名与C#方法名不同,可以在此指定函数的实际入口点名称。 5. **ExactSpelling**: 默认为`false`,表示允许.NET框架在找不到精确匹配的函数时尝试找到同名但大小写不同的函数。 6. **PreserveSig**: 默认为`true`,表示保持方法签名的原始返回类型不变。如果设置为`false`,则.NET会将所有非`void`返回类型转换为`int`。 7. **SetLastError**: 如果为`true`,则调用`SetLastError`方法后的错误信息可以通过`Marshal.GetLastWin32Error()`获取。 使用DllImport调用非托管DLL的示例: ```csharp [DllImport("kernel32")] private static extern long WritePrivateProfileString( string section, string key, string val, string filePath); ``` 在这个例子中,`WritePrivateProfileString`是Windows API中的一个函数,用于写入INI文件。C#中对应的类型映射如下: - `DWORD`通常映射为`int`或`uint`。 - `BOOL`映射为`bool`。 - 预定义常量通过`enum`来表示。 - 结构(`struct`)用来映射复杂的数据类型。 DllImport在寻找DLL时的搜索顺序如下: 1. **当前执行程序的目录**:这是首先查找的地方,如果你的DLL和C#程序在同一目录下,可以直接引用。 2. **System32目录**:系统的关键库通常存放在这里,如果没有在第一步找到,会尝试这里。 3. **环境变量指定的路径**:如`PATH`环境变量包含的路径,系统也会在这些路径下查找。 注意,为了确保程序的稳定运行,最好将依赖的非托管DLL与你的C#程序一起分发,或者将其放置在系统路径中,这样可以避免因找不到DLL而导致的运行时错误。同时,确保正确地映射所有数据类型,因为类型不匹配可能导致严重的问题,如数据溢出或内存损坏。