我有一个小程序,其中gtk信号回调函数需要2或3个变量.
我不想制作这些全局变量(项目的整个目标是整洁和整洁)我不想制作一个完整的结构,所以我可以将一个小部件和一个编译的正则表达式发送到一个函数.
据我所见,g_signal_connect只允许单个数据变量.
这样做最有效的方法可能是一个指向这两个对象的void指针数组吗?像这样的东西?
void * data[2];
data[0] = widget;
data[1] = compiledregex;
g_signal_connect(save,"clicked",G_CALLBACK(callbackfunction),data);
Run Code Online (Sandbox Code Playgroud)
小智 9
当然,您可以使用void指针数组,但是如果要传递具有不同类型的值(尤其是类型长于的值sizeof(void *)),则不能使用数组.对于这些,您几乎肯定希望将它们包装在结构中并将结构的地址作为数据参数传递.
例:
struct my_struct *data = malloc(sizeof(*data));
data->field_one = value_one;
data->field_two = value_two; /* etc. */
g_signal_connect(save, "clicked", callback, data);
Run Code Online (Sandbox Code Playgroud)
当然,不要忘记free(data)在回调函数中(假设它是单次使用).
编辑:你想要一个带有void**的例子,你在这里(这很丑陋,我不建议你使用它 - 或者因为为原始类型分配一个单元素数组而浪费你的拍摄或因为施法指向void*的非指针是不好的做法......):
void **data = malloc(sizeof(data[0]) * n_elements);
type1 *element1_ptr = malloc(sizeof(first_item));
*element1_ptr = first_item;
data[0] = element1_ptr;
/* etc. */
Run Code Online (Sandbox Code Playgroud)
解放他们:
int i;
for (i = 0; i < n_elements; i++)
free(data[i]);
free(data);
Run Code Online (Sandbox Code Playgroud)
您可以使用g_object_set_data()和g_object_get_data().首先,设置数据:
g_object_set_data(G_OBJECT(my_edit), "my_label", my_label);
g_object_set_data(G_OBJECT(my_edit), "age", GINT_TO_POINTER(age));
Run Code Online (Sandbox Code Playgroud)
在回调中,您可以获得如下数据:
gint age = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "age"));
GtkWidget *my_label = g_object_get_data(G_OBJECT(widget), "my_label");
Run Code Online (Sandbox Code Playgroud)