首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 庫轉 C# 可用 DLL:P/Invoke 完整實戰指南

     編輯:程式設計疑難解答

核心工具:pinvoke.net

微軟維護的 pinvoke.net 收錄了 Windows API 及常見 C 函式庫的 C# 簽名定義,**直接搜尋函數名複製貼上**即可。

四步走流程

1. 確認 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);

2. 編譯原生 DLL(Visual Studio)

  • 建立「動態連結庫 (DLL)」專案。
  • 實作函數,確保呼叫慣例為 __stdcall(Windows API 預設)或 __cdecl(C 預設),C# 預設 StdCall,若為 cdecl 需標註 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]。
  • 輸出 mylib.dll,放入 C# 專案輸出目錄(bin/Debug/x64 或 x86)。

3. C# 定義 P/Invoke 簽名


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

4. C# 呼叫並驗證


int sum = NativeMethods.add(3, 5); // 8
var sb = new StringBuilder(256);
NativeMethods.getString(sb, sb.Capacity);
Console.WriteLine(sb.ToString());

進階對照表

C 型別C# 封送型別備註
intint4 位元組有號
unsigned intuint
char* (in)string自動轉 ANSI/Unicode
char* (out)StringBuilder預分配容量
struct*ref Struct / out Struct結構體需 [StructLayout(LayoutKind.Sequential)]
callbackdelegate委託需保持存活防 GC

常見坑點

  • 32/64 位元不匹配:C# 專案 Prefer 32-bit 勾選狀態需與 DLL 一致,或分別提供 x86/x64 版 DLL。
  • 字串編碼:CharSet.Ansi vs CharSet.Unicode 必須與原生端一致。
  • 記憶體釋放:原生端 malloc 的記憶體需提供 free 函數,C# 呼叫釋放,否則洩漏。

總結:**pinvoke.net 查簽名 → 定義 extern → 注意呼叫慣例與位元寬度 → 測試驗證**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved