エラー メッセージにあるように、&StartHand::MouseButton
構文を使用してメンバ関数 (ptmf) へのポインタを取得する必要があります。これは単に言語の一部として義務付けられています。
ptmf を使用する場合、呼び出す関数 (この場合は glutMouseFunc) もコールバックとして ptmf を取得する必要があります。そうしないと、非静的 MouseButton を使用しても機能しません。代わりに、一般的な手法は、コールバックがユーザー指定のvoid*
コンテキスト (インスタンス ポインターの場合もあります) で動作することですが、コールバックを実行するライブラリでは、このパラメーターを明示的に許可する必要があります。また、外部ライブラリ (以下のhandle_mouse関数) が期待する ABI と一致することを確認することも重要です。
glutはユーザー提供のコンテキストを許可しないため、別のメカニズムを使用する必要があります: オブジェクトを glut の現在のウィンドウに関連付けます。ただし、「現在のウィンドウ」を取得する方法は提供されており、これを使用して avoid*
をウィンドウに関連付けました。次に、トランポリンを作成して型変換を行い、メソッドを呼び出すだけです。
機械:
#include <map>
int glutGetWindow() { return 0; } // make this example compile and run ##E##
typedef std::pair<void*, void (*)(void*,int,int,int,int)> MouseCallback;
typedef std::map<int, MouseCallback> MouseCallbacks;
MouseCallbacks mouse_callbacks;
extern "C" void handle_mouse(int button, int state, int x, int y) {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) { // should always be true, but possibly not
// if deregistering and events arrive
i->second.second(i->second.first, button, state, x, y);
}
}
void set_mousefunc(
MouseCallback::first_type obj,
MouseCallback::second_type f
) {
assert(obj); // preconditions
assert(f);
mouse_callbacks[glutGetWindow()] = MouseCallback(obj, f);
//glutMouseFunc(handle_mouse); // uncomment in non-example ##E##
handle_mouse(0, 0, 0, 0); // pretend it's triggered immediately ##E##
}
void unset_mousefunc() {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) {
mouse_callbacks.erase(i);
//glutMouseFunc(0); // uncomment in non-example ##E##
}
}
例:
#include <iostream>
struct Example {
void MouseButton(int button, int state, int x, int y) {
std::cout << "callback\n";
}
static void MouseButtonCallback(
void* self, int button, int state, int x, int y
) {
static_cast<Example*>(self)->MouseButton(button, state, x, y);
}
};
int main() {
Example obj;
set_mousefunc(&obj, &Example::MouseButtonCallback);
return 0;
}
もうglutMouseFuncを直接呼び出さないことに注意してください。[un]set_mousefuncの一部として管理されます。
明確でない場合に備えて、この回答を書き直して、あなたのために機能し、C/C++ リンケージの問題が議論されないようにします。そのままコンパイルして (glut なしで) 実行し、少し変更するだけで glut で動作するはず##E##
です。