我正在学习如何用C#调用C ++中的方法。我做了一些研究,看起来Pinvoke是一个不错的方式。
如何将这个简单的C ++代码转换为在C#中调用它的方式,以及如何编写要在C#中调用的方法?
我有一个头文件:
MathFuncsLib.h
namespace MathFuncs
{
class MyMathFuncs
{
public:
double Add(double a, double b);
MyMathFuncs getClass();
};
}
MathFuncsLib.cpp
#include "MathFuncsLib.h"
namespace MathFuncs
{
MyMathFuncs MyMathFuncs::getClass() {
return *(new MyMathFuncs());
}
double MyMathFuncs::Add(double a, double b) {
return a + b;
}
}
在C#中,
我想:
main()
{
MyMathFuncs abd = MyMathFuncs::getClass();
abd.Add(1.2, 2.3);
}
我不知道应该如何实现,所以我认为最好问一下。
答案 0 :(得分:7)
当你有很多静态函数时,P / Invoke更适合。您可以使用C++/CLI,这在您拥有一组C ++类或类的结构化域模型层次结构时更合适。这就是你如何使用你的样本:
.H:
namespace MathFuncs {
public ref class MyMathFuncs
{
public:
double Add(double a, double b);
};
}
.CPP:
namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b) {
return a + b;
}
}
.CS:
static class Program
{
static void Main()
{
MyMathFuncs abd = new MyMathFuncs();
abd.Add(1.2, 2.3);
}
}
如您所见,您不需要像C ++ / CLI那样使用getClass函数,您的MathFuncs类将成为一个完整的.NET类。
编辑:如果你想在非托管代码中进行实际计算(样本中的a + b),你可以这样做;例如:
.H:
namespace MathFuncs {
public ref class MyMathFuncs
{
public:
double Add(double a, double b);
};
class MyMathFuncsImpl
{
public:
double Add(double a, double b);
};
}
.CPP:
namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b) {
MyMathFuncsImpl *p = new MyMathFuncsImpl();
double sum = p->Add(a, b);
delete p;
return sum;
}
#pragma managed(push, off)
double MyMathFuncsImpl::Add(double a, double b) {
return a + b;
}
#pragma managed(pop)
}
在这种情况下,MyMathFuncsImpl :: Add是作为本机代码生成的,而不是IL(从C#调用是相同的)。有关如何混合托管代码和非托管代码的详细信息,请参阅此处:managed, unmanaged。
答案 1 :(得分:0)
除非yor构造函数是私有的,否则您不需要使用get类。 如果是公开的,请使用它:
main()
{
MyMathFuncs abd = new MyMathFuncs();
abd.Add(1.2,2.3);
}
如果您希望构造函数是私有的并使用getClass来获取类的实例,则应该将该方法设置为静态:
namespace MathFuncs
{
class MyMathFuncs
{
public double Add(double a, double b);
static MyMathFuncs getClass() { return new MyMathFuncs(); }
};
}
答案 2 :(得分:0)
在c ++ / cli或托管c ++中围绕你定义的类添加一个包装类。它就像一个可以直接与native c ++和c#
组合的层。答案 3 :(得分:0)
使用Microsoft Visual Studio(Express),我按照正常情况创建了类(当然没有main()
函数),但您可以选择编译为.dll
。优点是,该类将位于一个单独的文件中,该文件可以从您正在开发的其他应用程序中重用/调用。