2013-05-01 116 views
1

我已经获得了需要在C#应用程序中使用的第三方C/C++库(.dll,.lib,.exp和.h)。C++/CLI:将C++类ptr传递给非托管方法

ThirdPartyLibrary.h包含...

class AClass { 
public: 
    typedef enum { 
     green = 7, 
     blue = 16 
    } Color; 
    virtual int GetData()=0; 
    virtual int DoWork(Color, char *)=0; 
}; 

void * Func1(int, AClass **aClass); 

在我的C++/CLI的代码,我已经这样做了......

#include "ThirdPartyLibrary.h" 
using namespace System; 
using namespace System::Runtime::InteropServices; 

namespace Wrapper { 
public ref class MyBridgeClass 
{ 
private: 
    AClass* pAClass; 

public: 
    // C# code will call this method 
    void AMethod (int x) 
    { 
    int y = x+10; 
    Func1 (y, &(this->pAClass)); // <-- error! 
    } 
} 
} 

我得到读取生成错误...

cannot convert parameter 2 from 'cli::interior_ptr<Type>' to 'AClass **' 
     with 
     [ 
      Type=AClass * 
     ] 
     Cannot convert a managed type to an unmanaged type 

任何想法?也许我需要在我的C++/CLI中使用#pragma manage/unmanged标签?

回答

1

你得到这个错误的原因是因为管理内存的工作原理。

在您的托管类中,您定义了一个指针。该指针的地址是托管对象的一部分,并且可以在垃圾收集器运行时更​​改。这就是为什么你不能只将&pAClass传递给方法,GC可以改变实际的地址。

有几件事情可以做,以解决这个问题:

您可以创建一个非托管的辅助类来保持AClass*成员。如果这个指针需要在这个方法的调用之外保持有效,或者你有很多非托管指针要保持,我会这样做。

struct UnmanagedHolder 
{ 
    AClass* pAClass; 
}; 

public ref class MyBridgeClass 
{ 
private: 
    // must create in constructor, delete in destructor and finalizer. 
    UnmanagedHolder* unmanaged; 

public: 
    // C# code will call this method 
    void AMethod (int x) 
    { 
    int y = x+10; 
    Func1 (y, &(this->unmanaged->pAClass)); 
    } 
}; 

如果你只需要指针内amethod方法是有效的,并且指针不需要调用FUNC1后仍然有效,那么你可以使用一个pin_ptr。

void AMethod (int x) 
{ 
    int y = x+10; 
    pin_ptr<AClass*> pin = &(this->pAClass); 
    Func1 (y, pin); 
} 
+0

我知道固定,但我没有意识到非托管字段仍然分配在托管堆上。我添加了一个'this-> unmanaged = new UnmanagedHolder()'给桥接类'ctor,'if(this-> unmanged)'删除this-> unmanged'给桥接类'终结器。 – Tony 2013-05-01 17:03:24

相关问题