开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
上次我们尝试了C#调用C++ 的非托管方式,为了实现 C++ 和 C# 的更好的交互,我们这节来探讨一下C# 调用 C++/CLI 的托管方式。在项目开发的过程中,我们知道有些很好用的库仅仅是 C++ 编写的,要想将 C++ 和 C# 项目一起使用,有个好的方法就是:P Invoke。为了使二者更好的交互,可以将现有的 C++ 类库,封装成 C++/CLI(托管C++)。记住我们的目标 C# 调用 C++,那么我们就来一起尝试一下吧~
一、创建 C++ 项目
-
创建C++空项目
-
命名为 ManageLibrary
-
进入属性
-
可以导入提前生成的属性
-
添加现有属性表
-
或者手动配置如下属性
-
配置输出目录
$(SolutionDir)Build$(Platform)$(Configuration)
- 创建一个类
NativeClass.h
#pragma once
class NativeClass
{
private:
int nCount;
public:
NativeClass(void);
~NativeClass(void);
int GetCount(void);
void Increase(void);
void Clear(void);
};
NativeClass.cpp
#include "NativeClass.h"
NativeClass::NativeClass(void)
{
this->nCount = 0;
}
NativeClass::~NativeClass(void)
{
}
int NativeClass::GetCount(void)
{
return this->nCount;
}
void NativeClass::Increase(void)
{
this->nCount++;
}
void NativeClass::Clear(void)
{
this->nCount = 0;
}
二、将 C++ 类库封装成 CLI
CLI = Common Language Infrastructure,需要使用 CLI 的时候,我们就必须配置项目属性,设置公共语言运行时支持(/clr)。
- 关键字
ref加在类之前声明是CLI/CLR 。 ^处理对象(Object)操作,代替*指针gcnew代替new去分配内存
#pragma once
#include "NativeClass.h"
namespace ManageLibrary {
public ref class NativeClassEx
{
// TODO: 在此处为此类添加方法。
private:
NativeClass* m_pnClass;
public:
NativeClassEx(void)
{
this->m_pnClass = new NativeClass();
}
~NativeClassEx(void)
{
delete this->m_pnClass;
}
int GetCount(void)
{
return this->m_pnClass->GetCount();
}
void Increase(void)
{
this->m_pnClass->Increase();
}
void Clear(void)
{
this->m_pnClass->Clear();
}
protected:
!NativeClassEx(void)
{
delete this->m_pnClass;
}
};
}
三、C# 类库
-
创建C#项目
更多细节可以参考之前的文章的第三章,如果你不想当前的C#项目作为类库被调用你也可以创建C#的控制台应用程序。
-
解决方案右键 创建 C# 控制台应用程序
-
选择 Console App
-
命名为 ConsoleApplication
-
点击创建
-
设置 C# 的 ConsoleApplication 为启动项目
-
Build Dependencies:生成依赖项-项目依赖项
-
创建 cs 文件代码,测试 C++ CLI 动态库里的类函数
using System; using ManageLibrary; namespace ConsoleApp1 { class Program { static void Main(string[] args) { NativeClassEx testCalss = new NativeClassEx(); Console.WriteLine("GetCount : " + testCalss.GetCount().ToString()); testCalss.Increase(); testCalss.Increase(); testCalss.Increase(); Console.WriteLine("GetCount : " + testCalss.GetCount().ToString()); testCalss.Clear(); Console.WriteLine("GetCount : " + testCalss.GetCount().ToString()); Console.WriteLine("Hello World!"); } } }对于 C# 控制台应用程序,引用需要的 C++ CLI 动态库,使用 using 语句就可以使用对应的命名空间中的类及里面的函数。
-
测试结果如下