6

DirectShowを使用する小さなライブラリを作成しようとしています。このライブラリは.NETアプリケーションで利用されるため、C ++/CLIで作成するのが最適だと思いました。

しかし、私はこの行に問題があります:

    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;

};

このページを正しく理解していれば*/&、通常どおり、C ++/CLIライブラリのアンマネージメモリへの「ネイティブ」ポインタを示すことができます。^管理対象オブジェクトへのポインタを示すために使用されます。ただし、このコードは以下を生成します。

エラーC2440:'型キャスト':'cli::interior_ptr'から'void**'に変換できません

エラーは、それgraphBuilderがと見なされることを示してい'cli::interior_ptr<Type>'ます。それはマネージドメモリへのポインタ/ハンドルですよね?しかし、それは純粋なネイティブポインタです。ハンドルを期待するメソッドへのポインターを渡そうとはしていません。その逆も同様です。単にマネージドクラスに格納したいだけです)もしそうならgraphBuilder、「従来の」ポインターとはどういう意味ですか?

この質問は似ていますが、pin_ptrを使用するための答えは、クラスのメンバーになることができないため、私を助けてくれるとは思いません)

4

1 に答える 1

11

エラーメッセージは少しわかりにくいですが、コンパイラは、マネージクラスのメンバーへのポインタをアンマネージコードに渡すことができないことを通知しようとしています。これは設計上は機能しません。関数の実行中にガベージコレクターが起動し、管理対象オブジェクトを移動すると、災害が発生します。プロセス内のメンバーへのポインターを無効にし、ネイティブコードが間違ったアドレスの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...
    }
}
于 2012-05-06T18:03:00.777 に答える