C#中使用DllImport调用外部函数详解

需积分: 9 9 下载量 85 浏览量 更新于2024-11-22 收藏 40KB DOC 举报
"这篇资料主要介绍了C#中用于调用非托管DLL的DllImport特性,适合初级开发人员学习。" 在C#编程中,有时我们需要利用已经存在的非托管代码,例如Windows API或者其他C++编写的库函数。为了实现这一点,C#提供了一个名为`DllImport`的特性,使得开发者能够直接调用这些外部函数。`DllImport`位于`System.Runtime.InteropServices`名字空间中,它的主要作用是向.NET框架提供必要的信息,以便于从非托管DLL中导入函数。 `DllImportAttribute`是一个类,它作为属性应用于方法,告诉.NET框架该方法是用于调用非托管DLL中的函数。创建这个属性时,至少需要提供包含函数入口点的DLL的名称。以下是对`DllImportAttribute`的一些关键属性的详细说明: 1. dllName:这是`DllImport`构造函数的唯一必需参数,用于指定包含待调用方法的DLL文件名。例如,如果要调用Windows API中的`MessageBox`函数,就需要指定`User32.dll`。 2. CallingConvention:这个属性用于指定调用约定,即函数参数传递的方式。常见的调用约定有`StdCall`(默认值,适用于大多数Windows API函数)、`Cdecl`(C语言的调用约定)和`ThisCall`(主要用于COM组件)。如果没有明确指定,会使用`CallingConvention.Winapi`,它通常等同于`StdCall`。 3. CharSet:此属性定义了在DLL中使用的字符集,例如ASCII或Unicode。默认值是`CharSet.Auto`,它会自动检测并选择适当的字符集。还可以设置为`CharSet.Ansi`(使用ANSI字符集)或`CharSet.Unicode`(使用Unicode字符集)。 4. EntryPoint:如果DLL函数的名称与C#方法名不同,或者需要指定特定的函数入口点,可以使用这个属性。如果不指定,将会使用C#方法的名称作为入口点。 5. ExactSpelling:如果设置为`true`,则要求函数名称必须与DLL中的实际名称完全匹配,不允许.NET框架自动添加或移除任何下划线。 6. PreserveSig:默认情况下,`PreserveSig`为`true`,表示当非托管函数返回值不是`int`或`void`时,不会将其转换为异常。如果设置为`false`,则当返回值表示错误状态时,会抛出异常。 7. SetLastError:如果设置为`true`,则.NET框架会在调用非托管函数后检查`Win32`的`LastError`变量,并将其值暴露给C#代码。这对于诊断和调试非托管函数的错误非常有用。 通过使用`DllImport`,C#开发人员可以方便地调用C++或其他非托管语言编写的代码,无需重新实现功能,提高了代码复用性和效率。在实际工作中,确保正确设置上述参数对于正确调用非托管DLL至关重要。在编写代码时,一定要注意参数类型、调用约定和字符集的匹配,以避免出现兼容性问题。