Я пытаюсь подключить некоторые виджеты с одним и тем же обратным вызовом 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, ...
EDIT - этот вопрос является проблемой GTK +, потому что в первом g_signal_connect param1 - моя структура.Я в порядке, я знаю мою структуру, чтобы отбросить.Во втором g_signal_connect param1 является кнопкой GdkEventButton.Это тоже нормально, потому что я знаю, что это GdkEventButton для отбрасывания.НО, как это сделать, если я не знаю, что param1 является моей структурой, если это GdkEvent, GdkEventButton, gchar или все другие возможности синусных сигнатур?
РЕДАКТИРОВАТЬ 2 - я нашел эту информацию в Closures doc
Закрытия позволяют вызываемому объекту получать типы параметров обратного вызова, что означает, что языковые привязки не должны писать отдельный клей для каждого типа обратного вызова.
Это замечательно для того, что я ищу, но я не нашел ничего более, что оно
РЕДАКТИРОВАТЬ 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 - внутри обратного вызова, вернуть мою структуру с результатом custom + g_signal_query 5 - зациклить в param_types GSignalQuery, проверяя каждый фундаментальный тип 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);
}
Требуется исправить возврат и приведение в штучной упаковке, но с этим я могу нормально работать