利用 C++ Interop 封装 ISO C++ 对象, 供其他 .Net 语言使用
2019獨角獸企業重金招聘Python工程師標準>>>
???? .Net BCL 支持兩種互操作技術,模塊 級重用 P/Invoke 和組件級重用COM 互操作,
?
C++/CLI 除了支持以上兩種互操作以外,更支持代碼級重用, 稱為 C++ Interop,本文
?
僅舉例說明這種互操作技術。本例使用 ISO C++ 建立一個類 NativeLib, 計算并打印
?
兩個位置的直線距離,然后使用 C++/CLI 封裝在一個 NativeLibWrap 托管類里,提
?
供給 C# 主程序調用。
?
// NativeLib.h (ISO C++)
#include <iostream>
#include <cmath>
using namespace std;
?
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
?????
相關文檔說明,本文不再綴述。
轉載于:https://my.oschina.net/duluo180/blog/8498
總結
以上是生活随笔為你收集整理的利用 C++ Interop 封装 ISO C++ 对象, 供其他 .Net 语言使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 8,协议序列化组件NewLife.Ser
- 下一篇: 爱立信:用什么保持全球老大的地位?