微軟維護的 pinvoke.net 收錄了 Windows API 及常見 C 函式庫的 C# 簽名定義,**直接搜尋函數名複製貼上**即可。
// mylib.h
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
MYLIB_API int add(int a, int b);
MYLIB_API void getString(char* buf, int maxLen);
__stdcall(Windows API 預設)或 __cdecl(C 預設),C# 預設 StdCall,若為 cdecl 需標註 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]。mylib.dll,放入 C# 專案輸出目錄(bin/Debug/x64 或 x86)。
using System.Runtime.InteropServices;
internal static class NativeMethods {
// 簡單數值型
[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int add(int a, int b);
// 輸出字串緩衝區
[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void getString(StringBuilder buf, int maxLen);
}
int sum = NativeMethods.add(3, 5); // 8
var sb = new StringBuilder(256);
NativeMethods.getString(sb, sb.Capacity);
Console.WriteLine(sb.ToString());
| C 型別 | C# 封送型別 | 備註 |
|---|---|---|
int | int | 4 位元組有號 |
unsigned int | uint | |
char* (in) | string | 自動轉 ANSI/Unicode |
char* (out) | StringBuilder | 預分配容量 |
struct* | ref Struct / out Struct | 結構體需 [StructLayout(LayoutKind.Sequential)] |
callback | delegate | 委託需保持存活防 GC |
Prefer 32-bit 勾選狀態需與 DLL 一致,或分別提供 x86/x64 版 DLL。CharSet.Ansi vs CharSet.Unicode 必須與原生端一致。malloc 的記憶體需提供 free 函數,C# 呼叫釋放,否則洩漏。總結:**pinvoke.net 查簽名 → 定義 extern → 注意呼叫慣例與位元寬度 → 測試驗證**。