.Net BCL 支持兩種互操做技術,模塊 級重用 P/Invoke 和組件級重用COM 互操做,html
C++/CLI 除了支持以上兩種互操做之外,更支持代碼級重用, 稱爲 C++ Interop,本文ios
僅舉例說明這種互操做技術。本例使用 ISO C++ 創建一個類 NativeLib, 計算並打印編程
兩個位置的直線距離,而後使用 C++/CLI 封裝在一個 NativeLibWrap 託管類裏,提this
供給 C# 主程序調用。spa
// NativeLib.h (ISO C++)指針
#include <iostream>htm
#include <cmath>對象
using namespace std;blog
public struct Location內存
{
Location(double x, double y) : X(x), Y(y) { }
double X;
double Y;
};
public class NativeLib
{
public:
NativeLib(Location&, Location&);
void PrintDistance() const;
private:
Location firstLocation;
Location secondLocation;
double GetDistance() const;
};
// NativeLib.cpp (ISO C++)
#include "NativeLib.h"
NativeLib::NativeLib(Location& firstLocation, Location& secondLocation) :
firstLocation(firstLocation), secondLocation(secondLocation) {
}
double NativeLib::GetDistance() const {
double dx = firstLocation.X - secondLocation.X;
double dy = firstLocation.Y - secondLocation.Y;
double distance = sqrt(dx * dx + dy * dy);
return distance;
}
void NativeLib::PrintDistance() const {
cout << "The distance is " << GetDistance() << endl;
}
以上是 ISO C++ 代碼,要在爲了在託管平臺 下使用,定義一個包裝類 NativeLibWrap,
它引用一個 NativeLib (ISO C++)對象的指針,注意一個託管 對象不能直接包含一
個本地(ISO C++)對象,只能使用指針,這是 由垃圾收集機制決定的,本地堆內存屬於
非託管資源,所以 NativeLibWrap 類實現了 Dispose 模式,請參考個人另外一篇博客
—— .Net Dispose 模式與 C++/CLI 肯定性資源清理。
// NativeLibWrap.h (C++/CLI)
#pragma once
#include "NativeLib.h"
public value struct LocationWrap
{
LocationWrap(double x, double y) : X(x), Y(y) { }
double X;
double Y;
};
public ref class NativeLibWrap
{
public:
NativeLibWrap(LocationWrap, LocationWrap);
~NativeLibWrap();
void PrintDistance();
protected:
!NativeLibWrap();
private:
NativeLib* nativeLib;
};
// NativeLibWrap.cpp (C++/CLI)
#incude "NativeLibWrap.h"
NativeLibWrap::NativeLibWrap(LocationWrap firstLocationWrap, LocationWrap secondLocationWrap) {
Location firstLocation(firstLocationWrap.X, firstLocationWrap.Y);
Location secondLocation(secondLocationWrap.X, secondLocationWrap.Y);
this->nativeLib = new NativeLib(firstLocation, secondLocation);
}
NativeLibWrap::~NativeLibWrap() {
this->!NativeLibWrap();
}
NativeLibWrap::!NativeLibWrap() {
delete nativeLib;
}
void NativeLibWrap::PrintDistance() {
this->nativeLib->PrintDistance();
}
Compile the four files with:
cl /clr /LD NativeLibWrap.cpp NativeLib.cpp
將產生NativeLibWrap.dll
// NativeLibWrapTest.cs (C#)
internal static class NativeLibWrapTest
{
private static void Main() {
LocationWrap firstLocation = new LocationWrap(1, 1);
LocationWrap secondLocation = new LocationWrap(4, 5);
NativeLibWrap nativeLibWrap = new NativeLibWrap(firstLocation,
secondLocation);
nativeLibWrap.PrintDistance();
nativeLibWrap.Dispose();
}
}
Compile with:
csc /r:NativeLibWrap.dll NativeLibWrapTest.cs
輸出NativeLibWrapTest.exe
運行, 輸出The distance is 5
對於ISO C++ 自定義的struct, enum 等類型,爲了在其餘.Net 語言中調用,須要從新定義爲
value struct (或value class), enum class 等,若是隻是在C++/CLI中使用,則不須要從新定
義,由於C++/CLI 支持ISO C++ 與託管代碼的混合編程。
C++/CLI 也支持在本地類型中訪問託管對象,須要使用gcroot 模板,也比較簡單,能夠查閱MSDN
相關文檔說明,本文再也不綴述。