下表整理了 P/Invoke 在默認封送(marshalling)規則下,常見托管???非托管類型的對應關系。
內容主要依據微軟官方 Marshalling Data with?Platform?Invoke 文檔,并補充了常見指針/句柄用法與字符串緩沖區(StringBuilder
)注意事項。(learn.microsoft.com, learn.microsoft.com)
常見基礎數值與指針類型映射
Windows / Win32 類型 | C / C++ 類型 | C# 托管類型 | 說明 |
---|---|---|---|
VOID | void | void | 用于無返回值函數 |
HANDLE | void* | IntPtr / UIntPtr | 平臺相關指針大小 |
BYTE | unsigned char | byte | |
SHORT | short | short (Int16 ) | |
WORD | unsigned short | ushort (UInt16 ) | |
INT / LONG | int / long (32?bit) | int (Int32 ) | |
UINT / DWORD / ULONG | unsigned int / long | uint (UInt32 ) | |
BOOL | long (Win32) | bool / int | 4?字節;返回值時多用 bool |
FLOAT | float | float (Single ) | |
DOUBLE | double | double | |
SIZE_T | size_t | UIntPtr | 平臺相關大小 |
INT_PTR / LONG_PTR | intptr_t /long* | IntPtr | |
UINT_PTR | uintptr_t | UIntPtr |
提示:所有以
…_PTR
結尾的 Windows 類型(如HINSTANCE
,LPARAM
等)在 C# 中一般使用IntPtr
;這樣無論 x86 還是 x64 都能正確擴展。(stackoverflow.com)
字符與字符串相關映射
Windows / C 類型 | 默認托管類型 | 需要的 CharSet / MarshalAs |
---|---|---|
CHAR | char (System.Char ) | CharSet.Ansi 時為 ANSI,常見于舊 API |
WCHAR | char | CharSet.Unicode 下與 System.Char 對應 |
LPSTR / char* | string 或 StringBuilder | ANSI;[MarshalAs(UnmanagedType.LPStr)] |
LPCSTR / const char* | 同上(只讀) | |
LPWSTR / wchar_t* | string / StringBuilder | Unicode;UnmanagedType.LPWStr |
LPCWSTR / const wchar_t* | 同上(只讀) |
- 輸入字符串:直接用
string
即可,由運行時負責編碼轉換。 - 輸出 / 可讀寫字符串緩沖區:用
StringBuilder
并在參數前加[Out]
(默認 In/Out)。
但 .NET 9 及最新代碼分析規則 CA1838 建議改為手動分配字節緩沖區以減少復制開銷。(learn.microsoft.com, learn.microsoft.com)
結構體與數組簡表
非托管形態 | 典型托管聲明 | 關鍵屬性 |
---|---|---|
純 POD 結構體(順序字段) | [StructLayout(LayoutKind.Sequential)] struct Foo { … } | 如有字節對齊需求再加 Pack = N |
結構體指針 | ref Foo / out Foo / IntPtr | ref/out 讓 CLR 自動生成 Foo* 指針 |
數組輸入 | byte[] data | [In] 可省略 |
數組輸出或 In/Out | [Out] byte[] data / IntPtr | 需預分配長度并傳入;或用 IntPtr + Marshal.Copy |
若結構體包含指針或可變長成員(如
char*
),建議拆分為“句柄 + 訪問函數”的形式而不是直接封送復雜結構。(devblogs.microsoft.com)
獲取更多官方資源
- 微軟文檔: Marshalling Data with Platform Invoke 提供最權威、最完整的類型對照表及示例。(learn.microsoft.com, learn.microsoft.com)
- pinvoke.net: 社區維護的 API 定義倉庫,查看具體 Windows 函數的推薦托管簽名。(pinvoke.net)
- .NET Blog & DevBlogs: 深入了解各版本運行時對 interop 的改進與性能調優。(devblogs.microsoft.com, devblogs.microsoft.com)
(本篇文章由本人編寫,ChatGPT潤色)