0

我的 GTK 程序仍然有问题。

当我单击编码(或解码)按钮时,我收到错误消息:

分段故障

我认为问题来自功能:retencode找不到。

    //..
    //gets the first argument(buf)
    tx1=gtk_entry_get_text(GTK_ENTRY(entry));
    //...
    //gets the second argument(pass)
    tx2=gtk_entry_get_text(GTK_ENTRY(entry));
    //....
    //signal to callback function encode when button clicked
    g_signal_connect(but,"clicked",G_CALLBACK(encode(tx1,tx2)),NULL);
    // ...
    //convert const char* to char*
    char* ret (const char *bd){
    char *c = new char[12];
    strcpy(c,bd);
    return c;
} 

//encode function
char encode(const char ebuf[],const char epass[]) {
    //This is the complete function I wrote and I am still having the error.
    char *buf=ret(ebuf);
    char *pass=ret(epass);
}
4

2 回答 2

1

这条线没有意义:

g_signal_connect(but,"clicked",G_CALLBACK(encode(tx1,tx2)),NULL);

您正在encode()使用一些参数进行调用,它返回一个char值(顺便说一句未定义),然后您将其char转换为 a GCallback,这是一个指向函数的指针。然后,当单击按钮时,Gtk+ 将尝试调用您char的函数,这显然不是一个有效的函数,因此会出现分段错误。

不知道你想做什么,但你必须遵守规则,规则说"clicked"回调应该是一个带有这个原型的函数指针:

void f(GtkButton *button, gpointer user_data);

除此之外,你玩的真的很危险。

示例代码

比如说,你想encodechar*as 参数调用函数。你可以这样做:

void clicked_encode(GtkButton *button, gpointer user_data)
{
    char *d = static_cast<char*>(user_data);
    encode(d);
}

并注册回调

g_signal_connect(but, "clicked", G_CALLBACK(clicked_encode), text);

这假设指向的内存text至少与回调一样长。如果不是这种情况,你制作一个副本,但你必须记住释放它:

char *d = strdup(text);
g_signal_connect_data(but, "clicked", G_CALLBACK(clicked_encode), d, free_text, 0);

//and the deleter function
void free_text(gpointer *data, GClosure *)
{
    char *d = static_cast<char*>(data);
    free(d);
}

当然,您的函数中可能需要多个参数,但您只能传递一个指针。解决方案是定义一个包含所有内容的结构(或类,您正在使用 C++):

FancyClass *d = new FancyClass(...);
g_signal_connect_data(but, "clicked", G_CALLBACK(clicked_encode), d, free_fancy_class, 0);

void clicked_encode(GtkButton *button, gpointer user_data)
{
    FancyClass *d = static_cast<FancyClass*>(user_data);
    encode(d);
}

void free_fancy_class(gpointer *data, GClosure *)
{
    FancyClass *d = static_cast<FancyClass*>(data);
    delete d;
}

嘿!你甚至可以创建encode()一个成员函数FancyClass。可能性是无止境!

我希望这会让你走上正确的轨道......

于 2013-05-20T22:29:35.150 回答
0

如果您不想拥有更多动态大小的字符串,请使用 strncpy 限制要复制的字符数。

于 2013-05-20T21:35:12.040 回答