结构体中带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
相关产品推荐
相关产品推荐

