跳轉到內容

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