C#调用C++语言编写的动态链接库
引言
上一篇文章我们讲了,这篇文章我们就讲讲关于C#怎么样调用C++动态链接库。
C++动态链接库
我们先新建一个C++动态链接库项目,注意笔者开发环境为WIndows 10 x64 + Visual Studio Enterprise 2017。
新建cplusplus.h和cplusplus.cpp文件,cplusplus.h文件输入如下内容:
class CPLUSPLUS_API CCPlus
{
public:
CCPlus();
~CCPlus();
public:
int add(int a, int b);
int sub(int a, int b);
};
在cplusplus.cpp文件中输入以下内容:
using namespace std;
CCPlus::CCPlus()
{
cout << "CCPlus" << endl;
}
CCPlus::~CCPlus()
{
cout << "~CCPlus" << endl;
}
int CCPlus::add(int a, int b)
{
cout << "add" << endl;
return a + b;
}
int CCPlus::sub(int a, int b)
{
cout << "sub" << endl;
return a - b;
}
至此,代码我们已经写完了,接下来需要设置cplusplus工程属性,选中“cplusplus”工程->鼠标右键->属性->配置属性->常规->配置类型 更改为“动态库(.dll)”;还要设置预处理宏,在C/C++->预处理器->预处理器定义,在末尾输入";CPLUSPLUS_PORTS",注意双引号不要输入。设置完毕如下图所示:
设置完毕,Ctrl+Shift+B编译一下,结果如下所示:
至此,C++的项目就已经写好了。
C#调用
接下来我们试一下创建一个C#项目调用我们编写的C++动态库; 选中解决方案->鼠标右键->添加->新建项目,在弹出的窗口左侧找到Visual C#,中间选中“控制台应用(.NET Framework)”,在下方输入名称“CShape”,点击确定按钮完成项目的创建,如下所示:
我们先以上篇文章的方法测试一下,打开Program.cs文件,输入如下代码:
using System;
using System.Runtime.InteropServices;
namespace CShape
{
public class CPlus
{
[ ]
public static extern int add(int a, int b);
}
class Program
{
static void Main(string[] args)
{
CPlus.add(1, 2);
Console.ReadKey();
}
}
}
将CShape项目的输出路径改为“..\Debug\”(不含双引号,详见可参见上一篇文章),并将CShape设为启动项目。
按Ctrl+Shift+B编译一下,没有错误的话按F5快捷键运行,会发现运行不起来,报错了,如下图所示:
找不到名为“add”的入口点?可是我们明明在cplusplus项目中有add函数啊。这里所涉及的知识就太多了,本文不对其进行讲解,有兴趣的朋友可以网上查找相关资料。虽然不能像调用C那样调用C++,但是我们可以通过CLR将C++中转成C#可以调用的。
CLR
首先我们先新建一个CLR工程,选中“解决方法”->添加->新建项目,如下所示:
然后我们在CLR自动生成的CLR.h文件中写入如下内容:
using namespace System;
namespace CLR {
public ref class ClassCLR
{
public:
ClassCLR();
~ClassCLR();
int add(int a, int b);
int sub(int a, int b);
private:
CCPlus *m_pPlus;
};
}
在CLR.cpp文件中写入如下内容:
CLR::ClassCLR::ClassCLR()
:m_pPlus(new CCPlus)
{
}
CLR::ClassCLR::~ClassCLR()
{
delete m_pPlus;
}
int CLR::ClassCLR::add(int a, int b)
{
return m_pPlus->add(a, b);
}
int CLR::ClassCLR::sub(int a, int b)
{
return m_pPlus->sub(a, b);
}
确认无误后按Ctrl+Shift+B编译。至此C++和CLR项目都编写完了,接下来我们在C#调用CLR来达到调用C++动态链接库。
打开C#项目CShape,选中“引用”,鼠标右键->添加引用,选中刚刚创建的CLR项目,如下图所示:
在CShape的Program.cs文件中输入如下内容:
using System;
using System.Runtime.InteropServices;
namespace CShape
{
class Program
{
static void Main(string[] args)
{
CLR.ClassCLR clr = new CLR.ClassCLR();
Console.WriteLine(clr.add(1, 2));
Console.WriteLine(clr.sub(10, 20));
Console.ReadKey();
}
}
}
OK,确认无误全部编译后启动,效果如下:
至此成功调用了C++编写的类类型的动态链接库。
思考一下,如果C++动态链接库类成员函数接受的是std或指针类型的参数,C#该怎么处理?