2012-05-06 21 views
5

私はDirectShowを使用する小さなライブラリを作成しようとしています。このライブラリは.NETアプリケーションで利用されるので、C++/CLIで書くのが最善だと思いました。C++/CLIのリファレンスクラスで「ネイティブ」ポインタを使用するにはどうすればよいですか?

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

graphBuilderが宣言されています:

私はしかし、このラインでトラブルを抱えています私が正しくthis pageを理解していた場合

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

    IGraphBuilder* graphBuilder; 

}; 

、私は示すためにいつものように*/&を使用することができる「ネイティブ」私のC++/CLIライブラリのアンマネージメモリへのポインタ。 ^は、管理オブジェクトへのポインタを示すために使用されます。しかし、このコードが生成されます。

エラーC2440: '型キャスト':エラーがgraphBuilderがあると考えられていることを示唆している 'CLI :: interior_ptr' から '無効**'

に変換することはできませんがa '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

管理対象クラスの内部メンバーでもアンマネージドポインタを保持できないということは明らかです。これが真実なら、どのようにしてどのように一貫した方法で管理型と非管理型の間を橋渡しするのか、私の頭の中を包み込むようにしようとしています。 –

+0

いいえ、それはいいです。 OPはオブジェクトのメンバーである&graphBuilderへのポインタを作成しました。 –

関連する問題