2012-05-06 27 views
5

我想寫一個小型庫,它將使用DirectShow。這個庫將被.NET應用程序使用,所以我認爲最好用C++/CLI編寫它。如何在C++/CLI的引用類中使用'native'指針?

我有但是這條線的麻煩:

HRESULT hr = CoCreateInstance( CLSID_FilterGraph, 
            NULL, 
            CLSCTX_INPROC_SERVER, 
            IID_IGraphBuilder, 
            (void**)(&graphBuilder)); //error C2440: 

graphBuilder聲明:

public ref class VideoPlayer 
{ 
public: 
    VideoPlayer(); 
    void Load(String^ filename); 

    IGraphBuilder* graphBuilder; 

}; 

如果我理解正確this page,我可以使用*/&像往常一樣表示「天然」在我的C++/CLI庫中指向非託管內存的指針; ^用於表示指向受管理對象的指針。但是,此代碼產生:

錯誤C2440: '類型轉換':無法從 'CLI :: interior_ptr' 轉換爲 '無效**'

錯誤提示graphBuilder被認爲是一個'cli::interior_ptr<Type>'。這是一個託管內存的指針/句柄,不是嗎?但它是一個純粹的本地指針。我沒有試圖將指針傳遞給期望句柄的方法,反之亦然 - 我只是想將它存儲在我的託管類中)如果是這樣,請問graphBuilder如何成爲'傳統'指針?

This question相似,但答案,使用pin_ptr,我看不到幫助我,因爲它不能成爲我班的成員)

回答

9

該錯誤消息是有點神祕,但編譯器試圖提醒您不能將指向託管類成員的指針傳遞給非託管代碼。這不能通過設計工作,當垃圾收集器在執行函數時移動並移動託管對象時發生災難性的攻擊。使進程中成員的指針無效並導致本地代碼將字節傳輸到錯誤地址的gc堆中。

解決方法很簡單,只需聲明一個局部變量並將指針傳遞給它即可。堆棧上的變量不能移動。像這樣:

void init() { 
    IGraphBuilder* builder; // Local variable, okay to pass its address 
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     IID_IGraphBuilder, 
     (void**)(&builder)); 
    if (SUCCEEDED(hr)) { 
     graphBuilder = builder; 
     // etc... 
    } 
} 
+0

指針本身可以在設置時移動 - 我完全錯過了!謝謝漢斯! – sebf

+0

所以,爲了清楚起見,你說你不能將非託管指針保留爲託管類的內部成員?試圖圍繞我如何以任何一致的方式在託管和非託管類型之間架起橋樑,如果這是真的。 – 2014-10-12 18:58:33

+0

不,這很好。 OP創建了一個指向對象成員的指針,&graphBuilder。 –