我有一个用本机C ++编写的大型应用程序。我还有一个C#课,我需要打电话。
如果C#类是静态的,那么它将是微不足道的(网上有很多例子) - 只需编写混合的C ++ / CLI包装器,导出接口,然后就完成了。
但是,C#类是非静态的,并且不能更改为静态,因为它有一个接口(如果您尝试使C#类静态,编译器将生成错误。)
之前是否有人遇到此问题 - 如何将非静态C#类导出到本机C ++?
更新2010-11-09
最终解决方案:尝试COM,这很好用,但不支持结构。所以,使用C ++ / CLI包装器,因为我绝对需要能够在C ++和C#之间传递结构。我根据这里的代码编写了一个混合模式.dll包装器:
由于目标类是非静态的,我不得不使用单例模式来确保我只实例化目标类的一个副本。这确保了一切都足够快以满足规格。
如果您希望我发布一个演示项目,请与我联系(虽然,公平地说,我从C ++调用C#,而现在大多数人都想从C#调用C ++。)
答案 0 :(得分:10)
C ++ / CLI或COM interop与非静态类一样,与静态类一样。使用C ++ / CLI,您只需引用包含非静态类的程序集,然后使用gcnew
获取对新实例的引用。
是什么让你认为这对你的非静态课程是不可能的?
编辑:有示例代码here。
using namespace System;
public ref class CSquare
{
private:
double sd;
public:
CSquare() : sd(0.00) {}
CSquare(double side) : sd(side) { }
~CSquare() { }
property double Side
{
double get() { return sd; }
void set(double s)
{
if( s <= 0 )
sd = 0.00;
else
sd = s;
}
}
property double Perimeter { double get() { return sd * 4; } }
property double Area { double get() { return sd * sd; } }
};
array<CSquare ^> ^ CreateSquares()
{
array<CSquare ^> ^ sqrs = gcnew array<CSquare ^>(5);
sqrs[0] = gcnew CSquare;
sqrs[0]->Side = 5.62;
sqrs[1] = gcnew CSquare;
sqrs[1]->Side = 770.448;
sqrs[2] = gcnew CSquare;
sqrs[2]->Side = 2442.08;
sqrs[3] = gcnew CSquare;
sqrs[3]->Side = 82.304;
sqrs[4] = gcnew CSquare;
sqrs[4]->Side = 640.1115;
return sqrs;
}
答案 1 :(得分:3)
有两种选择。
答案 2 :(得分:1)
几年前我已经调查了这个主题:我想使用本机代码中的log4net和Npgsql库,即使没有/ clr密钥也可以编译。
Paul DiLascia在他的两篇引人注目的文章中描述了这种技术背后的主要思想:
Managed Code in Visual Studio 2005
Use Our ManWrap Library to Get the Best of .NET in Native C++ Code
这个解决方案的主要思想是gcroot智能指针和intptr_t在内存中具有完全相同的表示。我们创建了一个名为GCROOT(T)的宏,它在托管代码中使用gcroot,在非托管代码中使用intptr_t。我们使用本机接口和托管实现创建DLL,并使用本机代码中的这个dll。
我很容易为托管类创建一些适配器,并在原生C ++世界中使用它们,即使没有/ clr密钥也可以编译我的源代码。