You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

void与void*参数不兼容:新手如何正确传递void函数作为参数?

解决函数指针作为参数传入的问题

你的代码里的几个核心错误

  1. 传递函数的方式错误:你写glfwSetWindowShouldClose(window, GL_TRUE)的时候,是直接执行了这个函数,而不是传递它的指针。这个函数返回void,根本没法作为参数传入。
  2. 函数指针类型错误:用void* fun来接收函数指针不符合C++标准,而且就算编译过,直接写fun;也不会执行函数,只是对指针求值而已。
  3. 逻辑判断错误:key == keyname是把GLFW的键枚举值(比如GLFW_KEY_T)和扫描码(glfwGetKeyScancode的返回值)做比较,这两个值完全不是一回事,这个判断永远不会成立。

修正方案1:使用匹配的函数指针类型

因为你要传递的glfwSetWindowShouldClose签名是void(GLFWwindow*, int),所以先定义一个和它匹配的函数指针类型:

#include <GLFW/glfw3.h>

// 定义和目标函数签名一致的函数指针类型
using WindowAction = void(*)(GLFWwindow*, int);

然后修改你的standardKeyPressRelease函数,修正逻辑并正确调用传入的函数:

static void standardKeyPressRelease(GLFWwindow* window, int targetKey, int currentKey, int action, WindowAction fun, bool triggerOnPress) {
    // 先判断当前触发的键是否是目标键,再判断动作是否符合要求
    if (currentKey == targetKey) {
        if ((action == GLFW_PRESS && triggerOnPress) || (action == GLFW_RELEASE && !triggerOnPress)) {
            // 传入函数需要的参数,执行函数
            fun(window, GL_TRUE);
        }
    }
}

最后修改回调函数,正确传递函数指针:

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod) {
    // 传递函数名即可(函数名会隐式转为函数指针)
    standardKeyPressRelease(window, GLFW_KEY_T, key, action, glfwSetWindowShouldClose, true);
}

修正方案2:用std::function+lambda(更灵活)

如果以后要传递不同签名的函数,用std::function结合lambda封装会更方便,不需要关心原函数的参数:

#include <GLFW/glfw3.h>
#include <functional>

static void standardKeyPressRelease(GLFWwindow* window, int targetKey, int currentKey, int action, const std::function<void()>& fun, bool triggerOnPress) {
    if (currentKey == targetKey) {
        if ((action == GLFW_PRESS && triggerOnPress) || (action == GLFW_RELEASE && !triggerOnPress)) {
            // 直接调用封装好的无参函数
            fun();
        }
    }
}

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod) {
    // 用lambda把带参数的函数调用封装成无参的可调用对象
    standardKeyPressRelease(window, GLFW_KEY_T, key, action, [window](){
        glfwSetWindowShouldClose(window, GL_TRUE);
    }, true);
}

注意事项

  • 不要用static_cast或dynamic_cast把函数指针转成void*,这不符合C++标准,而且容易导致未定义行为。
  • 传递函数指针时,一定要保证函数签名和你定义的指针类型完全匹配,否则会编译错误或者运行时出错。

内容的提问来源于stack exchange,提问作者Tyrannys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:10:20