c#编程
Completion requirements
.NET Framework 与非托管代码互操作
.NET Framework 当前支持调用非托管函数和使用非托管数据,这一过程被称为“序列化”(marshalling)。这通常用于调用 Windows API 函数和数据结构,但也可以用于与自定义库的互操作。
GetSystemTimes
首先,来看一个简单的例子,使用 Windows API 函数 GetSystemTimes
。该函数的声明如下:
BOOL WINAPI GetSystemTimes(
__out_opt LPFILETIME lpIdleTime,
__out_opt LPFILETIME lpKernelTime,
__out_opt LPFILETIME lpUserTime
);
LPFILETIME
是指向 FILETIME
结构的指针,FILETIME
只是一个 64 位整数。由于 C# 通过 long
类型支持 64 位数值,因此我们可以使用 long
类型来处理它。我们可以通过以下方式导入并使用该函数:
using System;
using System.Runtime.InteropServices;
public class Program
{
[DllImport("kernel32.dll")]
static extern bool GetSystemTimes(out long idleTime, out long kernelTime, out long userTime);
public static void Main()
{
long idleTime, kernelTime, userTime;
GetSystemTimes(out idleTime, out kernelTime, out userTime);
Console.WriteLine("Your CPU(s) have been idle for: " + (new TimeSpan(idleTime)).ToString());
Console.ReadKey();
}
}
注意,使用 out
或 ref
关键字传递参数时,会自动将其视为指向非托管函数的指针。
GetProcessIoCounters
为了传递结构体的指针,可以使用 out
或 ref
关键字:
using System;
using System.Runtime.InteropServices;
public class Program
{
struct IO_COUNTERS
{
public ulong ReadOperationCount;
public ulong WriteOperationCount;
public ulong OtherOperationCount;
public ulong ReadTransferCount;
public ulong WriteTransferCount;
public ulong OtherTransferCount;
}
[DllImport("kernel32.dll")]
static extern bool GetProcessIoCounters(IntPtr ProcessHandle, out IO_COUNTERS IoCounters);
public static void Main()
{
IO_COUNTERS counters;
GetProcessIoCounters(System.Diagnostics.Process.GetCurrentProcess().Handle, out counters);
Console.WriteLine("This process has read " + counters.ReadTransferCount.ToString("N0") +
" bytes of data.");
Console.ReadKey();
}
}
通过这种方式,我们可以传递和接收结构体数据并从非托管代码中读取它们。
Last modified: Sunday, 12 January 2025, 12:40 AM