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

C# 與 C++ 互相呼叫 (一):C# 呼叫 C++ DLL 靜態/動態載入與 .NET 程式碼保護

     編輯:關於C#

背景動機

C# 易被反編譯 (ILSpy、dnSpy),核心演算法移植 C++ (機器碼難逆向),形成「核心 C++、周邊 C#」架構。需解決雙向互呼。

一、靜態載入 (P/Invoke) — 簡單直接

C++ DLL 專案

  • Win32 專案 → DLL
  • 匯出函式:extern "C" __declspec(dllexport) int Add(int a, int b)

// CppDemo.cpp
extern "C" __declspec(dllexport) int Add(int a, int b) {
    return a + b;
}

C# 端宣告與呼叫


using System.Runtime.InteropServices;

public class InteropDemo {
    [DllImport("CppDemo.dll", EntryPoint = "Add", CallingConvention = CallingConvention.Cdecl)]
    public static extern int Add(int a, int b);

    static void Main() {
        Console.WriteLine(Add(1, 2)); // 3
        // 需將 CppDemo.dll 放在輸出目錄 (bin\Debug) 或系統 PATH
    }
}

關鍵屬性

  • CallingConvention.Cdecl:C/C++ 預設呼叫慣例 (呼叫者清理堆疊),預設 `StdCall` 會導致堆疊不平衡。
  • EntryPoint:對應匯出函式名稱 (區分大小寫)。
  • DLL 必須與進程位元數一致 (x86/x64)。

二、動態載入 (LoadLibrary/GetProcAddress) — 彈性部署

適用:外掛架構、多版本 DLL、執行期決定路徑。

封裝 Kernel32 API


public static class NativeMethods {
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
    public static extern IntPtr LoadLibrary(string lpLibFileName);

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

    [DllImport("kernel32.dll", ExactSpelling = true)]
    public static extern bool FreeLibrary(IntPtr hModule);
}

動態取得委派並呼叫


public delegate int AddDelegate(int a, int b);

static void Main() {
    // 1. 載入 DLL (可用絕對路徑)
    IntPtr hMod = NativeMethods.LoadLibrary(@"C:\CppDemo.dll");
    if (hMod == IntPtr.Zero) {
        Console.WriteLine("LoadLibrary failed");
        return;
    }

    // 2. 取得函式位址
    IntPtr procAddr = NativeMethods.GetProcAddress(hMod, "Add");
    if (procAddr == IntPtr.Zero) {
        NativeMethods.FreeLibrary(hMod);
        return;
    }

    // 3. 轉為委派
    var add = Marshal.GetDelegateForFunctionPointer(procAddr);

    // 4. 呼叫
    Console.WriteLine(add(1, 2)); // 3

    // 5. 釋放
    NativeMethods.FreeLibrary(hMod);
}

三、.NET 程式碼保護補充策略

策略效果成本
核心邏輯移植 C++ DLL極高 (機器碼)開發維護雙語言
混淆器中 (阻擋新手)低
.NET Native / CoreRT / AOT高 (編譯為機器碼)工具鏈成熟度
關鍵演算法 Server 端執行最高 (原始碼不落地)架構複雜度

原始碼下載

完整範例專案 (C++ DLL + C# 靜態/動態呼叫)

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