张赐荣: C# 使用 dllimport 调用本机 Win32 API

C# 平台调用 (P/Invoke) 允许您在 C# 代码中调用本机动态链接库 (DLL) 中的函数。这使您能够在 .NET 应用程序中使用本机代码,或者在 .NET 应用程序中使用某些 Windows API 函数。
为了在 C# 中调用本机 DLL 中的函数,您需要使用 DllImport 属性。例如,以下代码使用 DllImport 属性调用 Windows API 函数 MessageBox:
using System.Runtime.InteropServices;
namespace PInvokeSample
{
class Program
{
[DllImport("user32.dll")]
static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
static void Main(string[] args)
{
MessageBox(IntPtr.Zero, "Hello, World!", "P/Invoke Sample", 0);
}
}
}
在这个例子中,DllImport 属性的第一个参数是要调用的 DLL 的名称(在这种情况下为 "user32.dll")。第二个参数是要调用的函数的名称。如果省略第二个参数,则默认使用 C# 方法的名称。
在调用本机 DLL 中的函数时,通常需要使用 Marshal 类来处理参数和返回值。例如,以下代码使用 Marshal.StringToHGlobalAnsi 方法将字符串转换为本机内存中的 ANSI 字符串,然后使用 Marshal.FreeHGlobal 释放内存:
[DllImport("mydll.dll")]
static extern void MyFunction(string str);
...
IntPtr pStr = Marshal.StringToHGlobalAnsi("Hello, World!");
try
{
MyFunction(pStr);
}
finally
{
Marshal.FreeHGlobal(pStr);
}
此外,还可以使用 MarshalAs 属性来指定如何在本机 DLL 中传递参数。例如,以下代码使用 MarshalAs(UnmanagedType.LPWStr) 指定字符串参数应以 Unicode 格式传递:
[DllImport("mydll.dll")]
static extern void MyFunction([MarshalAs(UnmanagedType.LPWStr)] string str);
MyFunction("Hello, World!");
下面是 MarshalAs 属性的一些常用值:
UnmanagedType.LPStr:ANSI 字符串
UnmanagedType.LPWStr:Unicode 字符串
UnmanagedType.Bool:布尔值
UnmanagedType.I1:字节
UnmanagedType.I2:短整型
UnmanagedType.I4:整型
UnmanagedType.I8:长整型
UnmanagedType.R4:单精度浮点数
UnmanagedType.R8:双精度浮点数
最后,还可以使用 SetLastError 属性来指示函数应将错误代码存储在本机错误代码变量中。例如:
[DllImport("mydll.dll", SetLastError = true)]
static extern bool MyFunction();
if (!MyFunction())
{
int errorCode = Marshal.GetLastWin32Error();
// 处理错误
}
希望本文能帮助您了解 C# 平台调用、DllImport、Marshal 和 MarshalAs 的工作原理。
 

猜你喜欢

转载自blog.csdn.net/zcr_59186/article/details/128415639