2016-04-10 24 views
0

コールバックを取ってC関数をラップしようとすると、メンバー関数が代理人とみなされるという問題が発生しました。 Cの関数は、デリゲートを取ることはないので、私は別のものに落ち着い:あなたが見ることができるように、私はメンバーになるデリゲートを(呼び出しリテラルコールバック設定機能に関数を渡しているこの関数はなぜデリゲートと見なされますか?

extern(C) void onMouse(void delegate(int, int, int) nothrow callback) 
{ 
    glfwSetMouseButtonCallback(handle, 
     function void (GLFWwindow* h, int button, int action, int mods) nothrow 
     { 
      callback(button, action, mods); 
     } 
    ); 
} 

私がここを通過する関数)。

エラーで
Error: function pointer glfwSetMouseButtonCallback (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int, int) nothrow) is not callable using argument types (GLFWwindow*, void delegate(GLFWwindow* h, int button, int action, int mods) nothrow @system) 

は、それがタイプvoid delegate通りであるとして、第2のパラメータを示しています

しかし、それは私が期待どおりに終わることはありません。

So.私の質問です:なぜこれが起こるのですか?明らかに分かるように、コードにはfunction voidと書かれています。

注:私はこれを見ました:Pass delegates to external C functions in D。 解決策は明らかにハックです。しかし、私はインターネット上で回避策を見つけることができない場合、私はそれを試してみます。

+0

"C"とC++の主な問題は、関数の* linkage *のようです。私には、CやC++リンケージであると思われる「デリゲート」は、あなたが望むものが何であるかは、あまり明確ではありません。 – tofro

+0

@tofroわかりません。デリゲートリテラルは単なる関数リテラルで、 'this'が付いているため、Cと互換性がなくなり、何らかの理由で関数リテラルに簡単に変換できなくなります。 –

+0

コンパイラのメッセージを注意深く見てください。 'glfwSetMouseButtonCallback()'が第2引数としてextern "C"関数ポインタを取ると言っています。しかし、代わりにC++の関数ポインタ( 'delegate')を渡しています。これら2つのタイプは互換性がありません。 – tofro

答えて

1

機能として宣言しても、それはできません。それはonMouseに渡すパラメータに依存しています。そのパラメーターはローカル変数であり、関数本体でそれらにアクセスすると、それらが代理人になります。あなたができることは、パラメータをfunctionに変更し、それを&callbackで渡すだけです(GLFWwindowをパラメータとして追加する必要があります)。

また、このコールバックがイベントを記録するグローバルリストを作成し、メインループで処理することもできます。

+0

私は本当にDが暗黙的に関数リテラルを代理リテラルに変換すべきではないと思います。それは私にかなりの混乱を与えました。 –

関連する問題