如何使用 g_signal_connect 传递整数

How to pass an integer using g_signal_connect

我正在尝试使用 g_signal_connect 将一个整数传递到我的函数中以显示按钮索引,但它会引发错误:

gui.c:35:39: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
       G_CALLBACK(button_clicked), (gpointer)row+column);
                                   ^
/usr/include/glib-2.0/gobject/gsignal.h:475:73: note: in definition of macro ‘g_signal_connect’
 g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
                                                                     ^~~~

这是我的代码:

#include <gtk/gtk.h>

void button_clicked(GtkWidget *widget, gpointer data) {
  g_print("Button %p clicked\n", data);
  gtk_button_set_label (GTK_BUTTON (widget), "X");
}

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {

  GtkWidget *window;
  GtkWidget *fixed;

  gchar *values[9] = {"1","2","3","4","5","6","7","8","9"};
  GtkWidget *button[9];

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "GtkFixed");
  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

  fixed = gtk_fixed_new();
  gtk_container_add(GTK_CONTAINER(window), fixed);

  for (int row = 0; row < 9; row+=3){
    for (int column = 0; column < 3; column++){

      button[row+column] = gtk_button_new_with_label(values[row+column]);
      gtk_fixed_put(GTK_FIXED(fixed), button[row+column], column*70, row*30);
      gtk_widget_set_size_request(button[row+column], 50, 50);
      g_signal_connect(G_OBJECT(button[row+column]), "clicked",
          G_CALLBACK(button_clicked), (gpointer)row+column);

    }
  }

  g_signal_connect(G_OBJECT(window), "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

我试过对行和列使用 gint 而不是 int,但这似乎没有任何改变。我做错了什么?

首先,表达式(gpointer)row+column等于((gpointer)row)+column,等于&((gpointer)row)[column]。这可能不是你所期望的。

其次,编译器很可能看不到 rowcolumn 永远不会为负。这可能会导致它生成错误的代码。使用 unsigned 作为 rowcolumn 的类型。

最后 "fixing" 你的警告:int 通常是 32 位,而你系统上的指针似乎比那个大(如果你使用的是 64 位,可能是 64系统)。您需要暂时转换为兼容整数和指针的类型。

将所有表达式放在一起应该类似于

(gpointer)(uintptr_t)(row+column)

然后在回调中你需要做相反的转换:

unsigned row_col = (unsigned)(uintptr_t)data;