【C#】调用DLL文件
程序员文章站
2022-06-24 22:30:14
...
实际使用C#的过程中,并不一定所有的函数都需要自己写,可以直接使用已经存在的功能,这些功能一般封装在DLL文件中。
C#中的DLL文件又分为托管DLL和非托管DLL。
托管DLL文件是在 .NET 环境下生成的dll文件,在公共语言运行库(Common Language Runtime,简称CLR)中能够直接引用的。比如封装各种命名空间的DLL文件,包括System.dll。
非托管DLL文件不是在 .NET 环境中生成的,是一般的动态链接库,不能在公共语言运行库中直接调用,需要经过 .Net框架提供的“平台调用”服务。以下只讨论非托管DLL文件的调用。
在托管代码中使用"平台调用"
服务调用非托管DLL中封装的函数时,“平台服务”将依次执行以下操作:
1. 定位包含该函数所在的DLL文件。
2. 将该DLL文件加载到内存中。
3. 定位函数在内存中的地址并将其参数推到堆栈上,根据需要封送数据。
4. 将控件转移给非托管函数。 这样整个函数调用完成。
MSDN中的平台调用数据类型中列出了非托管C类型和托管类型的替代关系。
使用DLLImport申明Windows API函数
DLLImport
定义如下:
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{
public DllImportAttribute(string dllName){...} //定位参数为dllName
public CallingConvention CallingConvention; //入口点调用约定
public CharSet CharSet; //入口点采用的字符集
public string EntryPoint; //入口点名称或序号
public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false
public bool PreserveSig; //方法的签名是被保留还是被转换
public bool SetLastError; //FindLastError方法的返回值保存在这里
public string Value {get {...}}
}
}
DllImport会按照顺序自动去寻找的地方:
1. exe所在目录
2. System32目录
3. 环境变量目录
典型例子:
/// [DllImport("xx.dll", EntryPoint="c++中方法名")]
/// public static extern void 转化后的C#方法名(bool b, int i);
/// 比如在C++类库中有个方法:void CFunction(bool b, int i);
/// 你在C#中调用时,先创建一个类
class CSClass
{
[DllImport("xx.dll", EntryPoint="CFunction")]
public static extern void CSFunction(bool b, int i);
}
/// 使用的时候就:
CSClass.CSFunction(true, 1); //方法名可以相同,不一定要改