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

结构体中带void*参数的函数指针传递编译报错求助

解决函数指针传递的编译错误问题

嘿,我来帮你拆解下你遇到的这两个编译错误:cannot convert to a pointer type 和 lvalue required as unary ‘&’ operand。

错误根源分析

你写的调用代码:

but1 = create_button(posbut, "test", BUTTON_DEF, &on_click((void *)box));

这里犯了两个关键错误:

  • 你先执行了on_click((void *)box)这个函数调用,然后试图取这个调用结果的地址。但on_click的返回类型是void——根本没有返回值,自然没法取地址。
  • 函数调用的结果本身不是左值(lvalue),&运算符只能作用在左值上,这就是第二个报错的原因。

简单说:你传递的不是函数指针,而是试图传递一个函数调用结果的地址,这完全不符合create_button对参数的要求。

正确的解决思路

C语言里没法直接给函数指针“绑定”参数(比如把box和on_click打包成一个指针传递),通常有两种标准解决方式:

方式1:修改create_button的参数设计(推荐)

让create_button同时接受函数指针和用户自定义数据指针,这样内部调用回调时可以把数据传进去。比如:

// 先修改create_button的声明,增加用户数据参数
Button* create_button(Pos pos, const char* text, int def, void (*on_click)(void*), void* user_data);

// 然后定义你的实际点击回调函数
void my_button_click(void* data) {
    Box* box = (Box*)data;
    // 这里写点击后的逻辑,操作box
}

// 调用create_button时,直接传函数指针和box指针
but1 = create_button(posbut, "test", BUTTON_DEF, my_button_click, (void*)box);

这种方式是C语言处理回调的标准做法,安全且可扩展。

方式2:如果无法修改create_button(不推荐的临时方案)

如果create_button只能接受void (*)(void*)类型的指针,且没法额外传用户数据,你只能用全局变量来存储box:

// 定义全局变量存储box
static Box* g_box;

// 包装回调函数
void on_click_wrapper(void* unused) {
    // 用全局的g_box来操作
    // ...
}

// 调用前先给全局变量赋值
g_box = box;
but1 = create_button(posbut, "test", BUTTON_DEF, on_click_wrapper);

这种方式要注意全局变量的线程安全问题,以及多个按钮时会互相覆盖数据,所以只适合简单场景。

补充说明

如果你用的是GCC编译器,可以用嵌套函数来实现类似参数绑定的效果,但这是非标准C特性,移植性差:

void create_my_button() {
    Box* box = ...; // 你的box变量
    // 定义嵌套函数,直接捕获外部的box变量
    void on_click_nested(void* unused) {
        // 直接使用box
        // ...
    }
    but1 = create_button(posbut, "test", BUTTON_DEF, on_click_nested);
}

但还是推荐用方式1的标准写法,兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:12:28