从C#/ .NET调用C ++函数

我有一个有C ++项目和C#项目的解决方案。

C ++项目定义了一个类,我想在C#中实例化并调用其成员函数。 到目前为止,我设法实例化了这个类:

CFoo Bar = new CFoo(); 

但是当我尝试在其上调用函数时,编译器说,它不可用。

此外,当我在调试器中检查对象时,不会显示任何成员。

我在这里想念的是什么?

您需要将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) }