Можете ли вы привести указатель на функцию такого типа:
void (*one)(int a)
к одному из этого типа:
void (*two)(int a, int b)
и затем безопасно вызвать указанную функцию с дополнительными аргументами, которые она была приведена для принятия? Я думал, что это незаконно, что оба типа функций должны быть совместимы. (Имеется в виду тот же прототип - то же возвращаемое значение, тот же список параметров.) Но это именно то, что, кажется, делает этот бит кода GTK + (взято из здесь ):
g_signal_connect_swapped(G_OBJECT(button), "clicked",
G_CALLBACK(gtk_widget_destroy), G_OBJECT(window));
Если вы посмотрите на сигнал «нажал» (или просто посмотрите на другие примеры его использования из первой ссылки), вы увидите, что его обработчики должны быть объявлены следующим образом:
void user_function(GtkButton *button, gpointer user_data);
Когда вы регистрируете обработчик с помощью g_signal_connect_swapped (), указатель виджета и аргументы указателя данных меняются местами по порядку, поэтому вместо этого объявление должно выглядеть следующим образом:
void user_function(gpointer user_data, GtkButton *button);
Вот проблема. Функция gtk_widget_destroy (), зарегистрированная как обратный вызов, прототипируется следующим образом:
void gtk_widget_destroy(GtkWidget *widget);
чтобы принять только один аргумент. Предположительно, поскольку указатель данных (GtkWindow) и указатель на виджет сигнализации (GtkButton) меняются местами, единственным полученным им аргументом будет указатель окна, а указатель кнопки, который будет передан после, будет молча игнорироваться , Некоторые Googling приводят похожие примеры, даже регистрацию таких функций, как gtk_main_quit (), которые вообще не принимают аргументов.
Правильно ли я считаю, что это нарушение стандартов? Нашли ли разработчики GTK + легальную магию, чтобы все это работало?