您的位置:首页 > 编程语言 > C语言/C++

利用 C++ Interop 封装 ISO C++ 对象, 供其他 .Net 语言使用

2010-10-01 00:00 429 查看
.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

相关文档说明,本文不再缀述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐