从C#程序中调用非托管 DLLs 的方法可以使用 P/Invoke,其作用是在 C# 代码中声明非托管函数并在 C# 中调用它们。
以下是从 C# 中调用非托管 DLL 的完整攻略:
步骤一:找到非托管 DLL,并获取该 DLL 中包含的函数及其参数。
通常,在VS中打开非托管 DLL 时,可以在 “Object Browser” 中查看 DLL 中导出的函数及其参数。如果 DLL 没有文档,可以使用工具如 Dependency Walker(Depends)或者 Object Manager 进行查看。
步骤二:在 C# 代码中声明该非托管函数。
使用 [DllImport]
特性来声明一个非托管函数。可以使用此特性显式的告诉 C# 编译器如何映射函数。
以下是一个示例:
[DllImport("User32.dll")]
static extern int MessageBox(IntPtr hWnd, String Text, String Caption, int Options);
上面所使用的 DLL 是Windows的 User32.dll 。函数是 MessageBox 函数,该函数用于显示一条消息,它有 4 个参数:窗口句柄,消息文本,消息标题和一些选项。
步骤三:调用非托管函数。
在 C# 中,你可以通过 Marshal
类来将参数从 C# 托管代码格式转换为非托管代码格式。例如,要显示对话框,调用 MessageBox
函数,可以使用以下代码:
int MB_YESNO = 0x00000004;
int result = MessageBox(IntPtr.Zero, "Are you sure?", "My Dialog Box", MB_YESNO);
如果用户单击 Yes,示例将返回 6,如果用户单击 No,该示例将返回 7。
下面是另一个示例,此示例将使用 LINQPad 软件调用一个非托管 DLL:
void Main()
{
const string dllPath = @"C:\Temp\CppLibrary.dll";
const string functionName = "add";
const int a = 5;
const int b = 7;
var sum = CallUnmanagedFunction<int>(dllPath, functionName, a, b);
sum.Dump();
}
T CallUnmanagedFunction<T>(string dllPath, string functionName, params object[] arguments)
{
var library = LoadUnmanagedDll(dllPath);
var targetFunction = library.GetProcAddress(functionName);
return Marshal.GetDelegateForFunctionPointer<T>(targetFunction)(arguments);
}
NativeLibrary LoadUnmanagedDll(string dllPath)
{
return NativeLibrary.Load(dllPath);
}
这个程序使用 NativeLibrary.Load
加载非托管 DLL,使用 NativeLibrary.GetProcAddress
获取非托管函数指针,最后使用 Marshal.GetDelegateForFunctionPointer
获取委托并调用非托管函数。
在这个例子中,非托管函数名为 add
,有两个 int 类型的参数并返回一个 int 类型的值。
总之,使用 P/Invoke 在 C# 程序中调用非托管 DLLs 的方法,是使用 C# 调用原生 Win32 API 程序的主要方法之一,这种方法对于访问直接使用 Win32 API 的 DLLs (尤其是像 User32.dll 中有太多需要直接使用的函数的 DLLs)是非常有用的。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:从C#程序中调用非受管DLLs的方法 - Python技术站