将C ++方法作为函数指针传递?

时间:2017-06-23 00:30:55

标签: c++ pointers glfw

我创建了一个名为InputControl的类。我正在使用一个名为GLFW的库和一个函数glfwSetKeyCallback。该函数定义为:

  

GLFWkeyfun glfwSetKeyCallback(GLFWwindow * window,GLFWkeyfun cbfun)

Typedef如下:

  

typedef void(* 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给出了以下错误

  

E0167类型&#34; void的参数(InputControl :: *)(GLFWwindow * window,int key,int scancode,int action,int mods)&#34;与&#34; GLFWkeyfun&#34;

类型的参数不兼容

2 个答案:

答案 0 :(得分: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);

}