下面就来详细讲解一下“P/Invoke之C#调用动态链接库DLL示例详解”的完整攻略。
概述
在 .NET Framework 中,和本机环境有关的操作都高度集成化了,大多数情况下是使用 .NET Framework 所提供的接口进行操作。但有些情况下需要直接使用本机的 API 接口才能完成特定的功能。在这种情况下我们可以使用 P/Invoke(Platform Invoke)机制调用 DLL 库。
P/Invoke
P/Invoke(平台调用)是 .NET Framework 的一部分,它允许 C# 代码调用本机(非托管)函数。P/Invoke 可以让我们在 .NET 代码中调用不同的本机 API。
P/Invoke 中的大多数操作涉及到 DLL(动态链接库,类似于 Windows 平台下的 .so 文件)。大多数情况下,我们使用 DLL 导出函数的名称和相关的参数,然后通过万能函数 DllImport
将其导入 C# 代码。
P/Invoke 示例 1
下面是一个简单的例子,演示如何使用 P/Invoke 调用 MessageBox
函数。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBox(int hWnd, String text, String caption, int options);
private void btnShowPopup_Click(object sender, EventArgs e)
{
MessageBox(0, "Hello, World!", "MessageBox Demo", 0);
}
在这个例子中,我们使用了 DllImport
,并指定了导入 user32.dll
的 MessageBox
函数。注意到这里使用的是 Auto
字符集。这意味着 .NET Framework 将根据 Windows 版本和当前线程的语言环境选择适当的字符集,所以我们不需要手动维护字符集。
函数的传递参数是十分简单的,因为和非托管函数 (例如 C 或 C++)非常相似。在这个例子中,我们传递了 4 个整数参数:一个窗口句柄、一个字符串消息、一个消息框的标题和一些规则选项。
最后,在按钮点击事件处理程序中,我们只需要调用 P/Invoke 函数即可显示 MessageBox
弹窗。
P/Invoke 示例 2
来看看一个稍微复杂一点的例子,这个例子演示如何调用 GetModuleHandle
函数获取一个模块的句柄。
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName);
private void btnGetModuleInfo_Click(object sender, EventArgs e)
{
IntPtr moduleHandle = GetModuleHandle(null);
StringBuilder stringBuilder = new StringBuilder(255);
uint result = GetPrivateProfileString("General", "AppName", "", stringBuilder, (uint)stringBuilder.Capacity, "app.ini");
MessageBox.Show($"Module handle: {moduleHandle}, App name: {stringBuilder.ToString()}");
}
在这个例子中,我们用到了两个使用 DllImport
导入的函数。这里调用 GetModuleHandle
函数获取当前模块的句柄(我们将传递空指针作为参数),然后将句柄赋给 moduleHandle
变量。
在下一行代码中,我们调用 GetPrivateProfileString
函数从 INI 文件中获取一些信息。在这个例子中,我们从文件 app.ini 中获取 "General" 标题下的 "AppName" 配置项的值。
最后,在点击按钮事件中,我们将模块句柄和从 INI 文件中获取的 "AppName" 值显示在 MessageBox 中。
总结
P/Invoke 是一个非常有用的机制,允许我们在需要本机 API 时,使用 .NET Framework 和 C# 代码实现不同的功能。虽然有些 P/Invoke 调用需要一些试验和错误,但你可以通过 MSDN 和大量的线上资源来找到所需的 API 和导出函数。通过这两个示例,你也可以了解到 P/Invoke 的简单步骤和简单示例。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:P/Invoke之C#调用动态链接库DLL示例详解 - Python技术站