天天看點

C#調用C++托管類,實作C#和C++的混合程式設計

  由于C#編寫的是托管代碼,編譯生成微軟中間語言,而C++代碼則編譯生成本地機器碼(這種C++也有叫做本地C++或者非托管C++,VC6.0就是用于開發非托管C++代碼的平台),這兩種語言進行混合程式設計就存在一定困難。比較常用的方法是使用DllImport的方法,這種方法在網上有很多介紹,這裡就不詳細叙述了。但是用過這種方法的人都知道這種方法對于導出函數還可以但是卻沒法導出非托管C++類!非常的要命。

然而,除了C#、非托管C++外,C系列中還存在一種語言叫做托管C++,這種語言文法上和非托管C++幾乎一樣,但是卻和C#一樣編譯成為微軟中間語言,這樣托管C++就可以和C#良好地通信,即可以在C#中使用托管C++類。另外,托管C++還有兩個及其重要的特性就是:可以調用非托管C++的類和函數!托管C++的程式集可以嵌套非托管C++編譯的機器碼!好強大的混合體。是以我們的技術路徑也就明晰了:C#以托管C++為中介調用非托管C++的類和函數。換句話說也就是用托管C++給非托管C++代碼做一個外殼包裝供C#調用。

環境:VS2017,Win10;

第一步:建立CLR C++類庫。将其命名為Test_DLL

C#調用C++托管類,實作C#和C++的混合程式設計

第二步:建立非托管方法 FunctionAdd類

FunctionAdd.h:

//這裡定義用于導出的C函數

int Add(int a, int b);

FunctionAdd.cpp:

#include "stdafx.h"

#include "FunctionAdd.h"

//這裡實作C函數(算術加法)

int Add(int a, int b)

{

 return a + b;

}

第三步:建立非托管類Native類

Native.h:

#pragma once

class Native

public:

   Native(void);

   ~Native(void);

   int menber;//用于導出的成員

   int menderFuncSub(int a, int b);//用于導出的成員函數,實作算術減法

};

Native.cpp:

#include "Native.h"

Native::Native(void)

   //構造

   menber = 1;

Native::~Native(void)

//這是非托管C++類實作的算術減法

int Native::menderFuncSub(int a, int b)

   return a - b;

第三步 建立托管類clrClass

clrClass.h:

#pragma once

//這是個托管C++類用于對C++本地代碼類和函數等進行封裝以在C#中使用

public ref class clrClass

//必須聲明為public,否則類在程式集中不可見,關鍵詞ref表示類是一個托管類,将編譯為中間語言

    clrClass(void);

   int menber;//這個成員通路非托管類CClassNative的公共成員(事實上隻需要包裝公共成員和公共成員函數,私有的包裝沒有意義,也包裝不了)

   int menderFuncSub(int a, int b);//這個成員函數用于包裝非托管類CClassNative的公共成員函數

   int menberFuncAdd(int a, int b);//這成員函數用于包裝C函數 int Add(int a,int b)

private:

    Native * native;//建立一個非托管類執行個體 (在構造函數中執行個體化,這裡可以了解為是為了在clrClass中“繼承”CClassNative的公共成員和方法)

clrClass.cpp:

#include "clrClass.h"

using namespace System;

clrClass::clrClass(void)

   native = new Native();//這裡一定注意要建立對象!

   menber = native->menber;//這裡是簡單舉例,最好用屬性方法來讀寫CClassNative類的成員,同C#相似,托管C++中有屬性函數,用法請自己查

//通過調用非托管類CClassNative的減法函數實作算術減法

int clrClass::menderFuncSub(int a, int b)

   return native->menderFuncSub(a, b);

//通過調用C函數實作算術加法

int clrClass::menberFuncAdd(int a, int b)

   return Add(a, b);

這樣就實作了clrClass對Native類和C函數int Add(inta,int b)的托管包裝。生成的Test_DLL.dll”就可以直接在C#中用了

第四步:建立WinForm程式,然後引用Test_DLL.dll

C#調用C++托管類,實作C#和C++的混合程式設計

代碼:

   public partial class Form1 : Form

   {

       clrClass clr = null;

       public Form1()

       {

           InitializeComponent();

           clr = new clrClass();

       }

       private void button1_Click(object sender, EventArgs e)

           int a = Convert.ToInt32(txtA.Text);

           int b = Convert.ToInt32(txtB.Text);

           //通過托管C++調用C函數int Add(int a,int b)實作的加法

           txtC.Text = clr.menderFuncSub(a, b).ToString();

       private void btnAdd_Click(object sender, EventArgs e)

           txtC.Text = clr.menberFuncAdd(a, b).ToString();

   }