好的,我正在编写一个创建整个面板的方法,它包含内容并将其添加到表单中。面板存储在一个阵列中。
这是基本想法。
void vscale1Event(GtkWidget *widget, int *vscale_id)
{
int value = gtk_range_get_value(GTK_RANGE(vscale_struct[*vscale_id]->vscale1));
do stuff with this value;
}
void add_vscale_panel(int vscale_id)
{
vscale_struct[vscale_id]->vscale1 = ..... ;
vscale_struct[vscale_id]->vscale2 = ..... ;
add buttons to form;
gtk_signal_connect(GTK_OBJECT(vscale_struct[button_id]), "value_changed", (GtkSignalFunc)vscale1Event, &vscale_id);
gtk_signal_connect(GTK_OBJECT(vscale_struct[button_id]), "value_changed", (GtkSignalFunc)vscale2Event, &vscale_id);
}
int main()
{
for (i = 0; i<n; i++)
{
add_vscale_panel(i);
}
}
我所遇到的问题是,当我移动比例时,我传入的&amp; vscale_id,后来变成了垃圾(它的值是一个大约32000的垃圾数字)。
但是 - gtk_signal_connect只被调用一次。 好吧,我知道它可能与调用堆栈有关,那个内存不再被保留。
但我之前为另一个小组做了同样的事情,并且它工作正常。 我改变了什么 - 试图让事情变得更加整洁。
之前的版本我将所有面板和小部件分别放在单独的数组中。 例如
GtkWidget **outerPanel;
GtkWidget **innerPanel1;
GtkWidget **vscale1;
而我正在做这件事:
typedef struct
{
GtkWidget **vscale1;
Gtkwidget **vscale2;
} V_Panel;
V_Panel **vscale_struct;
不打扰将面板放入阵列或结构中 - 因为我想我以后不需要访问它们? (我发现你可以回收&#39;标签,所以我计算面板(h和vbox),是相同的。
另外 - 一个有趣的线索 - 当我运行valgrind时 - 它工作正常。 valgrind如何改变程序使用它的记忆方式。
这里有什么帮助吗? 如果您可以解释在调用gtk_signal_connect时发生的事情。 -
这是我的实际代码:http://pastebin.com/MGfUihjM
相关的是 45,145,274,308,391答案 0 :(得分:2)
问题是你在堆栈上取一个变量的地址 - 在这种情况下是函数的参数。内存中的地址绝对不能保证继续保持您期望的值,因为它只是堆栈帧的一部分
将整数value_id
打包到回调用户数据指针中的正确方法是使用GINT_TO_POINTER
并使用GPOINTER_TO_INT
将其反转。
所以你的信号连接是:
gtk_signal_connect(GTK_OBJECT(vscale_struct[button_id]),
"value_changed",
(GtkSignalFunc)vscale1Event,
GINT_TO_POINTER(value_id));
在您的信号处理程序中看起来像:
void vscale1Event(GtkWidget *widget, gpointer userdata)
{
int vscale_id = GPOINTER_TO_INT (userdata);
int value = gtk_range_get_value(GTK_RANGE(vscale_struct[vscale_id]->vscale1));
do stuff with this value;
}