.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
相关文档说明,本文再也不缀述。