GTK+ g_pointer_connect错误地传递数据
GTK+ g_pointer_connect passing data incorrectly
使用 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_print输出"777"。但是,当函数被调用时
static void funct(gpointer data) {
g_print(std::to_string(*(guint*)data).c_str());
}
g_prints输出一些垃圾,例如:"81382720">
谁能帮我解决这个问题?
您正在传递指向局部变量 ( 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
来释放该指针,以避免内存泄漏。
编辑:
我错过了您的回调签名是错误的这一事实,因为它不尊重销毁信号之一。这是一个错误,必须修复。感谢el.pescado指出这一点。
对其他帖子的评论也是有效的,但不影响正确性:
-
GUINT_TO_POINTER
/GPOINTER_TO_UINT
可用于这种简单情况以避免动态分配 - 你打电话给
g_print
是不必要的复杂
首先,默认情况下,信号处理程序接收指向接收信号作为第一个参数的对象的指针,将用户数据作为最后一个参数。因此,信号处理程序应具有以下签名:
static void funct(GtkWidget *object, gpointer data) {
/* ... */
}
其次,x
是一个本地值,因此在调用回调时它可能(尽管不一定(超出范围。要修复它,你可以通过在堆上分配它来延长它的生命周期(g_new
、new
、malloc
(或让它成为全局/静态的。或者,由于uint
适合指针,因此您可以使用宏GUINT_TO_POINTER
/GPOINTER_TO_UINT
直接在指针中存储/检索x
。
最后,g_print
函数提供格式化输出,如printf
- 而不是创建临时std::string
并从中提取字符指针:
g_print(std::to_string(*(guint*)p).c_str());
您可以简单地使用%u
格式说明符来打印guint
:
g_print("%u", *p);
总结一下:
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 已经超出了范围,并且在调用窗口的"销毁"信号时调用回调时被销毁。因此,指针在取消引用时不再有效。
如果只想存储整数值,请使用 GINT_TO_POINTER()
来存储该值:
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);
}
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 在运行时处理类型擦除的数据-如何不重新发明轮子