我有一个包含C ++项目和C#项目的解决方案。
C ++项目定义了一个类,我希望在C#中实例化并调用其成员函数。到目前为止,我设法实例化了这个类:
CFoo Bar = new CFoo();
但是当我尝试在其上调用函数时,编译器说,它不可用。
此外,当我在调试器中检查对象时,不会显示任何成员。
我在这里缺少什么?
答案 0 :(得分:8)
您需要将C ++ / CLI中的类声明为ref class
。
(请注意,我们讨论的是C ++ / CLI,而不是C ++。我假设您必须在C ++项目中启用CLR,否则您将无法使新的CFoo
正常工作。)
修改强>
您无需将所有旧课程转换为ref
课程。
假设你有一些旧的C ++:
class FooUnmanaged
{
int x;
FooUnmanaged() : x(5) {}
};
然后尝试将其包装在CLR类中:
ref class FooManaged
{
FooUnmanaged m;
};
正如您所注意到的,您会收到错误消息,说明这是不允许的。但试试这个:
ref class FooManaged
{
FooUnmanaged *m;
};
那完全没问题。编译器不希望分配嵌入在托管堆上的对象内的非托管对象的实例,但是很高兴有一个指针,它在生成的IL中变为System.IntPtr
。
这意味着您必须决定如何致电delete
。最可能的解决方案是:
ref class FooManaged
{
FooUnmanaged *u;
public:
FooManaged(FooUnmanaged *u_)
: u(u_) { }
~FooManaged() { delete u; }
};
就像在任何其他C ++类中一样。在将来的某个版本中,C ++ / CLI可能会自动为我们进行此翻译。
请注意,生成的IL是FooManaged
类现在实现IDisposable
,并且析构函数已转换为Dispose
方法。这允许.NET客户端正确地解除分配它,例如在C#
using (var m = new FooManaged())
{
// end of block: m will be disposed (and so FooUnmanaged will be deleted)
}