2009-05-04 6 views
3

コールバックを登録するためにthirdpartyライブラリ登録関数を使用することが困難です。私はC++のCLIで書いていて、CやC++で書かれたライブラリにアクセスしています。C3374:デリゲートインスタンスを作成しない限り 'function'のアドレスを取得できません

上記のコンパイラエラーは何を意味しますか?

ベンダーによって定義されるように、これは登録機能である:

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask); 

ベンダーによって定義されるように、これはコールバックです:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam); 

私のコールバック関数:

public ref class Device 
{ 
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {}; 
} 

私の電話(失敗):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF); 
+0

複製を使用することができ、クラスのメンバー

すべきではない。 http://stackoverflow.com/questions/822526/how-do-i-register-a-callback-in-ac-library-from-my-cli-wrapper – lothar

+0

その質問は削除されました – MedicineMan

+0

私は自分の答えを広げました下方に。 – Promit

答えて

8

推測を賭けなければならない場合は、MANAGED関数のアドレスを取得してNATIVE関数ポインタとして渡そうとしています。それはまったく動作しません。ネイティブブリッジを作成する(難しく、おそらく利点がない)か、(これは簡単なアプローチです)、デリゲートを作成してMarshal.GetFunctionPointerForDelegateを使用してください。デリゲートは、ネイティブコードがコールバックすると予想される間、生き続ける必要があることを忘れないでください。おそらく、どこかに格納する必要があります。

ああ、refクラスまたはvalueクラスの中のすべての関数は、明確でない場合に備えて、管理された関数です。

[編集]コメントを隠す答えを広げる。最初のステップは、一致するデリゲートを作成することです。あなたが提供する機能のために、このように見えるようになるだろう:

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam); 

を次に、あなたは1を作成する必要があります:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc); 

そして、前述したように、あなたは、あなたのクラスでそれを保存する必要がありますが会員が消滅しないようにするためです。最後に、関数ポインタを取得して渡す必要があります。

すべてをカバーすると思います。あなたが必要とするのは、名前空間システムを使用することだけです。あなたは大丈夫でしょう。

+0

私はあなたが頭の爪に当たったと思います。あなたが提案するコードはどのように見えるのですか、必要なものは何ですか? – MedicineMan

+0

と、デリゲートを有効にして、収集されないようにする方法(ライフタイム管理) – MedicineMan

+0

以下の変更を行いました:1.デリゲートの作成が行方不明2.デリゲートのCallbackFuncDelegateをgcnewする^ del = gcnew CallbackFuncDelegate(&H8Device :: BtnCallBackFunc); – MedicineMan

0

あなたのコールバック関数はメンバーへのポインタであり、関数へのポインタは異なるものです。

でもPromitのソリューションで:

CallbackFuncDelegate(CallbackFunc) 

CallbackFuncはあなたが単に

public ref class Device 
{ 
    static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {}; 
} 

を書き、その後

Device::CallBackFunc 
+0

あなたの提案はコンパイルの問題を修正しましたが、プライベートデータにアクセスできない静的メソッド(何もできません)が今は奇妙に思えます。私はこれがうまくいくのだろうかと疑問に思う。 – MedicineMan

+0

まず、**静的**私的なデータにアクセスできる。 2番目 - あなたはシングルトンのようなものを作ることができます8)。このパターンを直接使用するか、オブジェクトへの静的関数と静的ポインタを持つデリゲートを作成します。 そして、ちょうどへのポインタメンバー問題について明確にする:あなたはここに がhttp://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=142 は長い話を作るために、いくつかのイントロを読むことができます 短い - あなたの最初の(静的ではない)コールバック関数が "this"ポインタを必要とする - その理由は、メンバへのポインタが違うからです。オブジェクトを持っている場合にのみ使用できます –

+0

提案をいただきありがとうございます。コールバックを使うために自分のクラスをシングルトンに変更することはどういうわけか、かなり正しいとは感じません。 – MedicineMan

関連する問題