2017-06-23 51 views
0

我创建了一个名为InputControl的类。我正在使用名为GLFW的库和函数glfwSetKeyCallback。该函数被定义为:作为函数指针传入C++方法?

GLFWkeyfun glfwSetKeyCallback(GLFWwindow *窗口,GLFWkeyfun cbfun)

的typedef如下:

无效的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中给了我下面的错误类型为void(InputControl :: *)的”

E0167参数( GLFWwindow * window,int key,int scancode,int action,int mods)“与参数类型”GLFWkeyfun“不兼容

+4

这是不可能的非静态类方法的指针转换为常规函数指针。这些是完全不同和不相容的实体。只要停止尝试这样做。不幸的是,你的问题没有提供足够的背景来提供替代解决方案。实际的'InputControl'对象在哪里? – AnT

+5

与您的问题无关,但不要使用两个前导下划线定义名称或符号。这些保留给所有范围内的编译器和标准库。请参阅[这个老问题和它的答案](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 
} 

您需要确保您的对象始终保持活动状态,只要您的窗口处于活动状态,并且没有其他任何操作将窗口的用户指针设置为除对象指针之外的任何其他内容。

+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); 

}