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

4

我有一个方案,其中包含一个C++项目和一个C#项目。

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

CFoo Bar = new CFoo();

但是当我尝试调用它的函数时,编译器表示该函数不可用。

此外,在调试器中检查对象时,没有显示任何成员。

我在这里缺少什么?


1
这个 C++ 项目是托管的还是非托管的? - Lasse V. Karlsen
如果您的意思是它使用了公共语言运行时支持(/clr),那么它已经被编译了。 - clamp
你有解决方案吗?请阅读我的帖子并帮我解决这个问题。 http://stackoverflow.com/questions/36929737/using-native-c-class-in-c-sharp - Zeeshan Maqsood
1个回答

9
你需要在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)
}

谢谢,如果我这样做,会出现很多错误,比如:Error 1 error C2814: a native type cannot be nested within a managed type。我猜这意味着我需要将成员更改为托管类型。有没有办法避免这种情况? - clamp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接