C++ GTK+g_指针_连接错误传递数据

C++ GTK+g_指针_连接错误传递数据,c++,gtk,C++,Gtk,在使用g_signal_connect时,我无法将数据传递给函数 guint x = 777; gpointer ptr = &x; g_print(std::to_string(*(guint*)p).c_str()); g_signal_connect(G_OBJECT(dialogWindow), "destroy", G_CALLBACK(funct), ptr); 这段代码中的g_打印输出777。但是,当调用funct时 static void funct(gpoin

在使用g_signal_connect时,我无法将数据传递给函数

guint x = 777;
gpointer ptr = &x;
g_print(std::to_string(*(guint*)p).c_str());
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), ptr);
这段代码中的g_打印输出777。但是,当调用funct时

static void funct(gpointer data) {
  g_print(std::to_string(*(guint*)data).c_str());
}
g_打印输出一些垃圾,如:81382720


有人能帮我吗?

我怀疑变量x已经超出范围,并且在调用回调时被销毁,而在调用窗口的销毁信号时被销毁。因此,指针在被取消引用时不再有效。

我怀疑变量x已经超出范围,并且在调用回调时被销毁,而在调用窗口的销毁信号时被销毁。因此,取消引用指针时,指针不再有效。

您将指针传递给局部变量x,并且在堆栈上分配局部变量。要使其在该函数范围之外保持活动状态,请在堆上分配它,或者可以选择使用静态或全局变量

guint *ptr = g_malloc(sizeof(guint));
*ptr = 777;
g_print(std::to_string(*ptr).c_str());
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), ptr);
当您不再需要它来避免内存泄漏时,不要忘记调用g_free来释放该指针

编辑:

我忽略了一个事实,即您的回调的签名是错误的,因为它不尊重销毁信号的签名。这是一个bug,必须修复。感谢佩斯卡多指出这一点

其他帖子上的评论也有效,但不影响正确性:

GUINT_TO_指针/GPOINTER_TO_指针可用于该简单情况,以避免动态分配 你打电话给g_print是不必要的
您正在传递一个指向局部变量x的指针,并且在堆栈上分配了一个局部变量。要使其在该函数范围之外保持活动状态,请在堆上分配它,或者可以选择使用静态或全局变量

guint *ptr = g_malloc(sizeof(guint));
*ptr = 777;
g_print(std::to_string(*ptr).c_str());
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), ptr);
当您不再需要它来避免内存泄漏时,不要忘记调用g_free来释放该指针

编辑:

我忽略了一个事实,即您的回调的签名是错误的,因为它不尊重销毁信号的签名。这是一个bug,必须修复。感谢佩斯卡多指出这一点

其他帖子上的评论也有效,但不影响正确性:

GUINT_TO_指针/GPOINTER_TO_指针可用于该简单情况,以避免动态分配 你打电话给g_print是不必要的
如果只想存储整数值,请使用GINT_to_指针存储该值:

guint x = 777;
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), GINT_TO_POINTER(x));
和GPOINTER_TO_INT来检索它:

static void funct(gpointer data) {
    guint x = GPOINTER_TO_INT(data);
}

如果只想存储整数值,请使用GINT_to_指针存储该值:

guint x = 777;
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), GINT_TO_POINTER(x));
和GPOINTER_TO_INT来检索它:

static void funct(gpointer data) {
    guint x = GPOINTER_TO_INT(data);
}

首先,默认情况下,信号处理程序接收指向接收信号的对象的指针作为第一个参数,用户数据作为最后一个参数。因此,您的信号处理程序应具有以下功能:

其次,x是一个局部值,因此在调用回调时,它可能不一定超出范围。要修复它,您可以通过在heap g_new、new、malloc上分配它来延长它的生命周期,或者使它成为全局/静态的。或者,由于uint适合指针,所以可以使用宏/直接在指针中存储/检索x

最后,函数提供格式化输出,如printf-而不是创建临时std::string并从中提取字符指针:

g_print(std::to_string(*(guint*)p).c_str());
您只需使用%u格式说明符即可打印吉尼特:

总而言之:

guint x = 777;
g_print("%u", x);
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), GUINT_TO_POINTER(x));

// ...

static void funct(GtkWidget *object, gpointer data) {
    g_print("%u", GPOINTER_TO_UINT(data));
}

首先,默认情况下,信号处理程序接收指向接收信号的对象的指针作为第一个参数,用户数据作为最后一个参数。因此,您的信号处理程序应具有以下功能:

其次,x是一个局部值,因此在调用回调时,它可能不一定超出范围。要修复它,您可以通过在heap g_new、new、malloc上分配它来延长它的生命周期,或者使它成为全局/静态的。或者,由于uint适合指针,所以可以使用宏/直接在指针中存储/检索x

最后,函数提供格式化输出,如printf-而不是创建临时std::string并从中提取字符指针:

g_print(std::to_string(*(guint*)p).c_str());
您只需使用%u格式说明符即可打印吉尼特:

总而言之:

guint x = 777;
g_print("%u", x);
g_signal_connect(G_OBJECT(dialogWindow), "destroy",
    G_CALLBACK(funct), GUINT_TO_POINTER(x));

// ...

static void funct(GtkWidget *object, gpointer data) {
    g_print("%u", GPOINTER_TO_UINT(data));
}

你有什么想法我怎么能修好它吗?你有什么想法我怎么能修好它吗?g_print的工作原理与printf:g_print%u,*p;g_print与printf类似:g_print%u,*p;