跳转到内容

C# 编程/ .NET 框架/封送

来自维基教科书,开放的书籍,面向开放的世界

.NET 框架目前支持调用非托管函数和使用非托管数据,这个过程称为封送。这通常用于使用 Windows API 函数和数据结构,但也可用于自定义库。

GetSystemTimes

[编辑 | 编辑源代码]

一个简单的例子是 Windows API 函数GetSystemTimes。它被声明为

BOOL WINAPI GetSystemTimes(
  __out_opt  LPFILETIME lpIdleTime,
  __out_opt  LPFILETIME lpKernelTime,
  __out_opt  LPFILETIME lpUserTime
);

LPFILETIME是指向FILETIME结构的指针,它只是一个 64 位整数。由于 C# 通过long类型支持 64 位数字,我们可以使用它。然后我们可以导入并使用该函数,如下所示

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();
    }
}

请注意,在参数中使用outref会自动将其变为指向非托管函数的指针。

GetProcessIoCounters

[编辑 | 编辑源代码]

要传递指向结构体的指针,我们可以使用outref关键字

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();
    }
}
华夏公益教科书