首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

Managed C++ 橋接實戰(一):C# 呼叫純 C++ 靜態函式庫

     編輯:C++ 入門

前言:取長補短,語言互操作的藝術

C# 擅長 UI、XML、資料庫、快速開發;C++ 擅長高效能演算法、底層硬體存取、舊有資產復用。Managed C++ (C++/CLI) 作為橋樑,讓兩者各司其職,少量膠水代碼即可打通任督二脈。

架構總覽

[C# UI 專案] → (參考) → [Managed C++ DLL] → (靜態連結) → [純 C++ Static Lib]

步驟 1:建立純 C++ 靜態函式庫


// PureCPPSLib.h
class PureCClass {
public:
    PureCClass();
    ~PureCClass();
    LPCTSTR getFirstName();
    void setFirstName(LPCTSTR firstName);
    LPCTSTR getLastName();
    void setLastName(LPCTSTR lastName);
    LPCTSTR joinName();
private:
    CString m_FirstName;
    CString m_LastName;
    CString m_FullName;
};

// PureCPPSLib.cpp
LPCTSTR PureCClass::joinName() {
    m_FullName = m_FirstName + _T(" ") + m_LastName;
    return (LPCTSTR)m_FullName;
}

編譯產出 PureCPPSLib.lib。

步驟 2:建立 Managed C++ 動態連結庫 (MgdLib)

專案屬性:Common Language Runtime Support (/clr),輸出類型:Dynamic Library。
引用 PureCPPSLib.lib 並包含頭檔。


// MgdLib.h
#using <mscorlib.dll>
#include "PureCPPSLib.h"

namespace MgdLib {
    public ref class mgClass {
    public:
        mgClass();
        ~mgClass();           // 解構子 (IDisposable)
        !mgClass();           // 終結子 (Finalizer)
        property String^ FirstName {
            String^ get();
            void set(String^);
        }
        property String^ LastName {
            String^ get();
            void set(String^);
        }
        String^ JoinName();
    private:
        PureCClass* m_pImpObj;  // 原生指標
    };
}

// MgdLib.cpp
using namespace MgdLib;
using namespace System;
using namespace System::Runtime::InteropServices;

mgClass::mgClass() { m_pImpObj = new PureCClass(); }

mgClass::!mgClass() { delete m_pImpObj; }  // 釋放非受控資源

mgClass::~mgClass() { this->!mgClass(); }  // 實作 IDisposable

String^ mgClass::FirstName::get() {
    return gcnew String(m_pImpObj->getFirstName());
}

void mgClass::FirstName::set(String^ str) {
    pin_ptr<const wchar_t> wch = PtrToStringChars(str);
    m_pImpObj->setFirstName((std::wstring)wch).c_str());
}

// LastName 同理...

String^ mgClass::JoinName() {
    return gcnew String(m_pImpObj->joinName());
}

關鍵技術點解析

  1. pin_ptr:釘住 Managed 字串記憶體,防止 GC 移動,安全取得原生指標。
  2. gcnew String(...):將原生 const wchar_t* 轉為 Managed String^。
  3. 處置模式:~mgClass() 呼叫 !mgClass(),確保確定性釋放原生物件。
  4. std::wstring 中介轉換:確保字元編碼一致 (UTF-16)。

步驟 3:C# 專案呼叫

  1. 加入對 MgdLib.dll 的參考。
  2. using MgdLib;
  3. UI 程式碼:

private void btnConnect_Click(object sender, EventArgs e) {
    mgClass myC = new mgClass();
    myC.FirstName = txtFirstName.Text;
    myC.LastName = txtLastName.Text;
    txtFullName.Text = myC.JoinName();
}

建置相依性順序

    PureCPPSLib (Static Lib) → MgdLib (Managed DLL) → C# App

Visual Studio 方案中設定專案相依性,確保建置順序正確。

執行結果


介面示意圖


運行結果:姓名合併顯示

結語

此模式將「高效能核心邏輯」封裝於純 C++,透過 Managed C++ 薄層包裝暴露給 C#。核心優勢:原生效能零損失、記憶體管理邊界清晰、C# 享有完整物件導向介面。下篇將示範反向呼叫:C++ 觸發 C# UI。

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