如何在回调中使用结构的参数化成员函数?
How to use parametrized member function of a struct in callback?
我有一个类似于下面的结构
struct dc_callback
{
int
my_configure_event(
GtkWidget *widget,
GdkEventConfigure *event,
struct LoadData *myData)
{
...others
return TRUE;
}
//Parametrized Constructor
int
my_draw(
GtkWidget *widget,
cairo_t *cr,
struct LoadData *myData)
{
...others
return TRUE;
}
};
它有两个参数化成员函数,我打算从 g_signal_connect
调用第 n 次。
main(){
int i;
dc_callback dc_callback_instance[nth];
for(i=0;i<nth;i++){
g_signal_connect(widget_list[i],"draw",G_CALLBACK(dc_callback_instance[i].my_draw),myData);
g_signal_connect(widget_list[i],"configure-event",G_CALLBACK(dc_callback_instance[i].my_configure_event),myData);
}
}
但是,在编译期间,我收到有关无效使用成员函数的错误 int dc_callback::my_draw(args)
。它要求我添加 ()
但无法完成,因为 G_CALLBACK 接受没有附加参数的函数名称。
我该如何完成?
G_CALLBACK
需要一个(非成员)函数指针,而您没有使用正确的语法来传递函数指针。然而,还有一个更大的问题:函数指针和成员函数指针在C++中是不同的概念。您不能将成员函数指针传递给需要标准函数指针的接口。
那么,如何将回调的调用与您的 dc_callback
实例相关联?
传统上,在使用 C 风格 API 时,您必须为将您的实例(和任何额外数据)作为 void*
参数的回调提供一个免费函数。然后在回调中,您可以将 void*
转换回原始类型。在您的情况下,这可能类似于:
struct CallbackData {
dc_callback& dc_callback_inst;
Foo otherData; // whatever else you need to capture here
};
void my_draw_cb(void* data) { // g_signal_connect might pass more params to cb in addition to data
CallbackData& cbData = *(CallbackData*)data;
cbData->dc_callback_inst.my_draw(cbData->otherData);
}
// ...
for(i=0;i<nth;i++){
CallbackData cbData{dc_callback_instance[i], myData};
g_signal_connect(widget_list[i],"draw",G_CALLBACK(&my_draw_cb),cbData);
// ...
}
@0x5453 的答案是正确的,除了 my_draw_cbk 和它的调用:应该是
gboolean my_draw_cbk ( GtkWidget *widget,
cairo_t *cr,
struct CallbackData *cbData)
{
cbData->dc_callback_inst.my_draw(widget, cr, cbData->otherData);
return TRUE;
}
并连接信号:
// cbData shall be free with g_free when no longer needed
CallbackData* cbData = g_new(CallbackData, 1);
// set the cbData values..
g_signal_connect(widget_list[i],"draw",G_CALLBACK(my_draw_cb),cbData);
我有一个类似于下面的结构
struct dc_callback
{
int
my_configure_event(
GtkWidget *widget,
GdkEventConfigure *event,
struct LoadData *myData)
{
...others
return TRUE;
}
//Parametrized Constructor
int
my_draw(
GtkWidget *widget,
cairo_t *cr,
struct LoadData *myData)
{
...others
return TRUE;
}
};
它有两个参数化成员函数,我打算从 g_signal_connect
调用第 n 次。
main(){
int i;
dc_callback dc_callback_instance[nth];
for(i=0;i<nth;i++){
g_signal_connect(widget_list[i],"draw",G_CALLBACK(dc_callback_instance[i].my_draw),myData);
g_signal_connect(widget_list[i],"configure-event",G_CALLBACK(dc_callback_instance[i].my_configure_event),myData);
}
}
但是,在编译期间,我收到有关无效使用成员函数的错误 int dc_callback::my_draw(args)
。它要求我添加 ()
但无法完成,因为 G_CALLBACK 接受没有附加参数的函数名称。
我该如何完成?
G_CALLBACK
需要一个(非成员)函数指针,而您没有使用正确的语法来传递函数指针。然而,还有一个更大的问题:函数指针和成员函数指针在C++中是不同的概念。您不能将成员函数指针传递给需要标准函数指针的接口。
那么,如何将回调的调用与您的 dc_callback
实例相关联?
传统上,在使用 C 风格 API 时,您必须为将您的实例(和任何额外数据)作为 void*
参数的回调提供一个免费函数。然后在回调中,您可以将 void*
转换回原始类型。在您的情况下,这可能类似于:
struct CallbackData {
dc_callback& dc_callback_inst;
Foo otherData; // whatever else you need to capture here
};
void my_draw_cb(void* data) { // g_signal_connect might pass more params to cb in addition to data
CallbackData& cbData = *(CallbackData*)data;
cbData->dc_callback_inst.my_draw(cbData->otherData);
}
// ...
for(i=0;i<nth;i++){
CallbackData cbData{dc_callback_instance[i], myData};
g_signal_connect(widget_list[i],"draw",G_CALLBACK(&my_draw_cb),cbData);
// ...
}
@0x5453 的答案是正确的,除了 my_draw_cbk 和它的调用:应该是
gboolean my_draw_cbk ( GtkWidget *widget,
cairo_t *cr,
struct CallbackData *cbData)
{
cbData->dc_callback_inst.my_draw(widget, cr, cbData->otherData);
return TRUE;
}
并连接信号:
// cbData shall be free with g_free when no longer needed
CallbackData* cbData = g_new(CallbackData, 1);
// set the cbData values..
g_signal_connect(widget_list[i],"draw",G_CALLBACK(my_draw_cb),cbData);