将C 方法作为功能指针传递

Passing in C++ Method as a Function Pointer?

本文关键字:指针 功能 方法      更新时间:2023-10-16

我创建了一个名为InputControl的类。我正在使用一个名为GLFW的库和功能GLFWSETKEYCALLBACK。该功能定义为:

glfwkeyfun glfwsetkeycallback(glfwwindow *窗口,glfwkeyfun cbfun(

typedef如下:

typedef void( * glfwkeyfun((glfwwindow *,int,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类型" void(inputcontrol :: *(的参数(glfwwindow *窗口,int键,int scancode,int action,int mods("与类型" glfwkeyfun"

的参数不相容

非静态成员函数需要一个对象才能进行。您需要一个非成员功能或静态成员函数作为回调。如果您绝对需要在回调内访问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对象指针外,其他任何东西都没有设置窗口的用户指针。

您可以拥有一个调用您的成员函数的接口:

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