首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 呼叫自訂 C++ DLL 完整實戰:參數封送與指標處理

     編輯:關於C#

背景與策略

專案需復用 C/C++ 既有模組 (加密演算法、硬體驅動等)。三種方案:重寫 (成本高)、COM 封裝 (註冊麻煩)、P/Invoke 呼叫原生 DLL (最輕量)。本文記錄從簡單到複雜的參數封送驗證過程。

C++ DLL 導出定義

// 統一導出巨集
#define LIBEXPORT extern "C" __declspec(dllexport)

// 1. 簡單整數運算
LIBEXPORT int MySum(int a, int b) { return a + b; }

// 2. 字串輸入/輸出 (呼叫端配置緩衝區)
LIBEXPORT void MyStrCopy(char* input, char** output)
{
    *output = _strdup(input); // 分配記憶體,呼叫端需釋放
}

// 3. 整數輸出參數
LIBEXPORT int MySumOut(int a, int b, int* result)
{
    *result = a + b;
    return *result;
}

C# 封送對應驗證歷程

階段 1:基本型別

[DllImport("MyLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int MySum(int a, int b);
// 測試通過

階段 2:字串輸出 - 關鍵突破

C++ 回傳 char** (指標的指標),C# 必須用 ref string 或 out string,並設 CharSet = CharSet.Ansi:

[DllImport("MyLib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void MyStrCopy(string input, out string output);

// 使用
MyStrCopy("Hello", out string result);
Console.WriteLine(result); // Hello
// 注意: C++ 端 _strdup 配置的記憶體需額外匯出 Free 函式釋放,否則洩漏

階段 3:整數輸出參數

[DllImport("MyLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int MySumOut(int a, int b, out int result);

// 使用
MySumOut(2, 3, out int sum); // sum = 5

關鍵封送對照表

C++ 型別C# 封送型別關鍵屬性
int, long (4 bytes)int, int
char* (輸入)stringCharSet.Ansi / Unicode
char** (輸出)out string / ref stringCharSet.Ansi, 記憶體由 C++ 配置
int* (輸出)out int / ref int
struct*ref StructType[StructLayout(LayoutKind.Sequential)]
回呼函式指標delegate委派實例必須保持存活防 GC

避坑指南

  1. CallingConvention:C/C++ 預設 Cdecl (呼叫端清理堆疊),.NET 預設 StdCall (被呼叫端清理)。必須顯式指定。
  2. CharSet:字串參數務必指定 Ansi 或 Unicode,避免自動查找導致不匹配。
  3. 記憶體所有權:C++ 配置、C++ 釋放。匯出 FreeString(char*) 供 C# 呼叫釋放。
  4. 結構體對齊:[StructLayout(LayoutKind.Sequential, Pack = 1)] 對應 C++ #pragma pack(1)。
  5. 64 位相容:指標型別用 IntPtr,long 在 C++ 為 4 位元組,C# 為 8 位元組,勿混用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved