2013-05-01 120 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

相關問題