2017-06-23 13 views
0

私はInputControlというクラスを作成しました。私はGLFWとglfwSetKeyCallbackというライブラリを使用しています。次のようにC++メソッドを関数ポインタとして渡すか?

typedefのがある

GLFWkeyfun glfwSetKeyCallback(GLFWwindow *ウィンドウ、GLFWkeyfunのcbfun):

のtypedefボイド(* GLFWkeyfun)(GLFWwindow *、int型の関数は次のように定義され、int、int、int)

私のメソッドを関数ポインタに変換できないという問題があります。私はそれを可能な限りあらゆる方法でキャストしようとしたような気がします。このメソッドをキャストする必要があるかどうかはわかりません。相対的なメソッドを関数ポインタとして渡すことに特有のものがありますか? 私のコードは次のとおりです。

#pragma once 
#include <GLFW/glfw3.h> 
#include "config.h" 

class InputControl { 
public: 
    void bind(); 
    void unbind(); 

private: 
    void __glfw__keycallback_bind(GLFWwindow* window, int key, int scancode, int action, int mods); 
}; 

InputControl.cpp

void InputControl::bind() { 
    glfwSetKeyCallback(__application__window, __glfw__keycallback_bind); 
} 

void InputControl::unbind() { 

} 

void InputControl::__glfw__keycallback_bind(GLFWwindow * window, int key, int scancode, int action, int mods) { 
//... other code here 
} 

Visual Studioは、ボイド(InputControl :: *)」タイプの

E0167引数私に次のエラーを与えます( GLFWwindow * window、int key、int scancode、intアクション、int mods) "は、" GLFWkeyfun "タイプのパラメータと互換性がありません

+4

通常の関数ポインタに非静的クラスメソッドポインタを変換することはできません。これらは完全に異なる、互換性のない性質の実体です。これをやろうとするのをやめてください。あなたの質問は、残念ながら、代替的な解決策を提供するのに十分な状況を提供していません。実際の 'InputControl'オブジェクトはどこにありますか? – AnT

+5

質問には関係ありませんが、2つの先頭のアンダースコアを使用して名前やシンボルを定義しないでください。これらはすべてのスコープでコンパイラと標準ライブラリ用に予約されています。詳細については、[この古い質問とその回答](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier)を参照してください。 –

+0

@AnTのコメントで拡大しています。メソッドはクラス***のインスタンスに対して動作します。通常の関数では、どのインスタンスを処理するかを決める方法がありません。 –

答えて

3

非スタティックメンバ関数は、作業にはオブジェクトが必要です。コールバックとしてメンバー以外の関数または静的メンバー関数が必要です。あなたは絶対にコールバックの内側にあなたのInputControlクラスのインスタンスにアクセスする必要がある場合は、glfwSetWindowUserPointer()を使用して、ウィンドウのユーザポインタを設定することができ、その後、コールバックは、非静的メンバ関数を呼び出すためにそのポインタを使用することができます。

class InputControl { 
public: 
    void bind(); 
    void unbind(); 

private: 
    static void keyCallbackStatic(GLFWwindow* window, 
            int key, 
            int scancode, 
            int action, 
            int mods); 
    void keyCallback(GLFWwindow* window, 
         int key, 
         int scancode, 
         int action, 
         int mods); 
}; 

void InputControl::bind() { 
    glfwSetWindowUserPointer(applicationWindow, this); 
    glfwSetKeyCallback(applicationWindow, keyCallbackStatic); 
} 

void InputControl::keyCallbackStatic(GLFWwindow* window, 
            int key, 
            int scancode, 
            int action, 
            int mods) 
{ 
    InputControl* that = static_cast<InputControl*>(glfwGetWindowUserPointer(window)); 
    that->keyCallback(window, key, scancode, action, mods); 
} 

void InputControl::keyCallback(GLFWwindow* window, 
           int key, 
           int scancode, 
           int action, 
           int mods) 
{ 
    // Do whatever 
} 

InputControlオブジェクトがあなたのウィンドウと同じ長さの間だけ生きていることを確認することはあなた次第であり、それ以外のものはウィンドウのユーザポインタをInputControlオブジェクトポインタ以外に設定するものはありません。

+1

あなたは私にそれを打つ。私はちょうど同じ答えを投稿しようとしていた;-) –

0

あなたのメンバ関数を呼び出すインターフェイスを持つことができます:

class App { 
public: 
    void onKeyDown(int key, int action) { 
     if (action == 1) 
      std::cout << "Pressed: " << static_cast<char>(key) << '\n'; 
     if (action == 0) 
      std::cout << "Released: " << static_cast<char>(key) << '\n'; 
    } 
}; 

class Interface { 
public: 
    static void* p; 

    static void OnKeyDown(GLFWwindow * window, int key, int scancode, int action, int mods) { 
     ((App*)(p))->onKeyDown(key, action); 
    } 
}; 
void * Interface::p; 

int main() 
{ 
    App app; 

    [...] 

    glfwSetKeyCallback(window, Interface::OnKeyDown); 

} 
関連する問題