gpt4 book ai didi

c++ - 有没有办法忽略信号签名?

转载 作者:行者123 更新时间:2023-11-28 01:21:22 25 4
gpt4 key购买 nike

我正在尝试使用相同的 user_function 回调连接一些小部件。在某些情况下,信号具有不同的签名。

搜索我发现 gtk_signal_connect_full,我想。

例如我的代码:

int MyObject::connect()
{
callback_object ....

// Create the callback
int ret = g_signal_connect(instance, "clicked", G_CALLBACK (connect_callback), callback_object);
int ret = g_signal_connect(instance, "button-release-event", G_CALLBACK (connect_callback), callback_object);

// Return handler id
return ret;
}

void MyObject::connect_callback(GObject *passedInstance, gpointer param1, gpointer param2)
{
// Return to st_callback
struct st_callback *callback_object = (struct st_callback *) param2;
if(sizeof(param1) == 0) {
callback_object = (struct st_callback *) param1;
}

}

我可以像那样“抽象”user_function 吗?如果可以的话,如何获得额外的参数,如 GdkEvent 或 GdkEventButton,或 gchar,...

编辑- 这个问题是一个 GTK+ 问题,因为在第一个 g_signal_connect 中,param1 是我的结构。没关系,我知道要回退的结构。在第二个 g_signal_connect 中,param1 是一个 GdkEventButton。也没关系,因为我知道它是一个要回退的 GdkEventButton。但是,如果我不知道 param1 是我的结构,如果它是 GdkEvent、GdkEventButton、gchar 或所有其他信号签名的可能性,该怎么做?

编辑 2- 我在 Closures doc 上找到了这个信息

Closures allow the callee to get the types of the callback parameters, which means that language bindings don't have to write individual glue for each callback type.

这看起来非常适合我正在寻找的东西,但我没有找到更多的东西

编辑 3

关于ebassi ideia,g_signal_query正是我所需要的。我这样做是为了摘要:

1 - 使用 g_signal_query 查询信号的参数,设置到我的结构中以通过回调 user_data 传递2 - 连接 g_cclosure_new_swap 和 g_signal_connect_closure,这将 gpointer user_data 设置为第一个参数3 - 像这样创建回调:connect_callback(gpointer user_data, ...),带有可变参数列表4 - 在回调中,用自定义 + g_signal_query 结果取回我的结构5 - 循环到 GSignalQuery 的 param_types,验证每个基本类型6 - 获取类型正确的 va_arg

调用回调的完整代码

    // Create gpoint param
struct st_callback *callback_object = (struct st_callback *)malloc(sizeof(struct st_callback));
memset(callback_object, 0, sizeof(struct st_callback));

callback_object->callback_name = callback_name;
callback_object->callback_params = callback_params;

// Get params of signal
GSignalQuery signal_info;
g_signal_query(g_signal_lookup (callback_signal, G_OBJECT_TYPE (instance)), &signal_info);

// Save
callback_object->signal_id = signal_info.signal_id;
callback_object->signal_name = signal_info.signal_name;
callback_object->itype = signal_info.itype;
callback_object->signal_flags = signal_info.signal_flags;
callback_object->return_type = signal_info.return_type;
callback_object->n_params = signal_info.n_params;
callback_object->param_types = signal_info.param_types;

GClosure *closure;
closure = g_cclosure_new_swap (G_CALLBACK (connect_callback), callback_object, NULL);
int ret = g_signal_connect_closure (instance, callback_event, closure, TRUE);

和回调

static bool connect_callback(gpointer user_data, ...)
{
// Return to st_callback
struct st_callback *callback_object = (struct st_callback *) user_data;

// get parameters count
int param_count = callback_object->n_params;
va_list ap;
va_start(ap, param_count);

// loop paramters
for (int i=0; i<param_count; i++) {

switch (G_TYPE_FUNDAMENTAL(callback_object->param_types[i])) {
case G_TYPE_CHAR:

break;
case G_TYPE_UCHAR:

break;
case G_TYPE_STRING:
{
char *path = va_arg(ap, char *);
break;
}
case G_TYPE_OBJECT:

break;
case G_TYPE_POINTER:

break;
case G_TYPE_INTERFACE:

break;
case G_TYPE_PARAM:

break;
case G_TYPE_BOXED:
{
// Example, try to cast correct boxed
GdkEvent *e = va_arg(ap, GdkEvent *);

break;
}
}
}

va_end(ap);
}

需要更正 return 和 boxed cast,但有了这个我可以正常工作

最佳答案

您不应该对不同类型的回调使用相同的函数。一些回调采用不同的参数,其他回调具有不同的返回值——例如,在您的示例中,clicked 不返回任何内容,而 button-press-event 返回一个 bool 值。

如果您有需要在不同信号处理程序中执行的通用代码,请编写一个函数,然后从各种处理程序中调用它。

关于c++ - 有没有办法忽略信号签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56105233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com