2013-08-07 6 views
6

私は、関数ポインタと任意のユーザデータ(void*)を必要とするC functionの周りにラッパーを書こうとしています。関数ポインタ私はデリゲートを使用して対処する方法を考え出しましたが、objectvoid*に変換する方法を理解することはできません。オブジェクトをvoid *に変換して戻しますか?

それは私の知る限り、ポインタのように振る舞うので、私は、代わりにそれをref objectを作ることができますが、私は

無効なVARIANTはに管理されていないVARIANTから変換中に検出されたような例外を得ることをしようとすると、管理対象オブジェクト。無効なVARIANTをCLRに渡すと、予期しない例外、破損またはデータの損失が発生する可能性があります。

This "solution"は私のために働くかもしれないが、私はそれは後で戻って渡すことができるように、C DLLに任意のデータを渡す方法がなければならない考え出しましたか?

+1

IntPtrはどうですか? –

+0

個人的には、 'fixed'ブロックを介して' struct'へのポインタを使う方が良いと思います... –

+0

@NoIdeaForName:C DLLは 'IntPtr'でも問題はありませんが、どうすればいいですか?それが返ってきたら 'object'に戻します(また、オブジェクトをIntPtrにどのように 'キャスト'するのでしょうか)? – mpen

答えて

2

私は個人的には、structを使用するようアドバイスします。これはあなたがやろうとしていることにさらに適用できます(必要に応じて内部レイアウトを調整することもできます)。例えば、struct Foo、基準型fooフィールドで:

unsafe void Bar() 
{ 
    fixed (Foo* ptr = &foo) // here foo is a field on a reference-type 
    { 
     void* v = ptr; // if you want void* 
     IntPtr i = new IntPtr(ptr); // if you want IntPtr 
     // use v or i here... 
    } 
} 

注:fooローカル変数である場合、それはスタックにあるとさえする必要がありませんfixedこと:

unsafe void Bar() 
{ 
    Foo foo = new Foo(); 
    Foo* ptr = &foo; // here foo is a local variable 

    void* v = ptr; // if you want void* 
    IntPtr i = new IntPtr(ptr); // if you want IntPtr 
    // use v or i here... 
} 
+0

2番目のビットについての質問 - 'foo'がスタックにある場合、スタックの最後にスタックからポップされませんこの関数は、C DLLにダングリングポインタを残していますか? – mpen

2

私はあなたがPointer.BoxPointer.UnBox方法が必要だと思う間違っていないよ場合。 これらのメソッドは、アンマネージドポインタのボックスとアンボックスに役立ちます。 Pointer.BoxPointer.UnBoxをmsdnでチェックしてください。

+0

私がこの権利を読んでいるなら、これは後方に聞こえる。 'Box'は、"提供されたアンマネージドメモリポインタ "を期待しています。 C DLLは私に 'void *'を与えてくれていません。私はそれを渡すために生成する必要があります。そして、 ''オブジェクト 'が最初にボックス化されていない限り、 'Unbox'は失敗するとはかなり確信しています。 – mpen

+0

+1うわー!私は 'Pointer.Box'を知らなかった! – xanatos

+0

'userdata'の実際のタイプは何ですか? –

関連する問題