当我 运行 使用 Glade 的 GTK 时,我收到以下警告 - 找不到信号处理程序 'on_window_main_destory'。你用-rdnamic编译了吗?

When I run a GTK with Glade I get the following warning - Could not find signal handler 'on_window_main_destory'. Did you compile with -rdnamic?

#include <gtk/gtk.h>
#include <curl/curl.h>
#include <iostream>
#include <string>

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

void pop_class()
{
    CURL *curl;
    CURLcode res;
    std::string readBuffer;

    curl = curl_easy_init();

    if(curl) 
    {
        curl_easy_setopt(curl, CURLOPT_URL, "http://api.openweathermap.org/data/2.5/forecast id=2158867&appid=a4f247bfd153738d2cd1757224361972");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }

}

int main(int argc, char *argv[])
{
    GtkBuilder      *builder; 
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new_from_file("glade/window_main.glade");

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    gtk_builder_connect_signals(builder, NULL);

    g_object_unref(builder);

    gtk_widget_show(window);                
    gtk_main();

    pop_class();

    return 0;
}

// called when window is closed
void on_window_main_destroy()
{
    gtk_main_quit();
}

这可以正确编译

g++ -c -g -O0 -Wall -pthread -pipe src/main.cpp -lcurl `pkg-config --cflags --libs gtk+-3.0` -o main.o

然后这个

g++ -o temp_app main.o -pthread `pkg-config --cflags --libs gtk+-3.0`
-export-dynamic

在 运行 我收到以下警告 -

Could not find signal handler 'on_window_main_destory'. Did you compile with -rdnamic?

GTK Builder 并不是真正设计用于与 C++ 或其他语言中的信号回调进行交互; C++ 函数是所谓的 name mangled,这意味着特定函数的真实名称可能与源代码中给出的函数名称完全不同。您的 on_window_main_destroy 函数实际上可能有一个类似这样的名称:_Zxl65Abvon_window_main_destroyxxj,具体取决于所使用的编译器。进行此重整是为了对函数的命名空间、参数类型和 return 值等进行编码,以便重载可以工作——也就是说,这样您就可以拥有两个或更多具有相同名称的不同函数, 但它接受或 return 不同的参数。

因此我真的建议在 window 上使用 g_signal_connect 函数,像这样:

g_signal_connect (window, "destroy", G_CALLBACK (on_window_main_destroy), NULL);

但是,如果您必须从 Builder 文件引用回调,则用 extern "C" { } 块包围回调函数,例如:

extern "C"
{
    void on_window_main_destroy()
    {
        gtk_main_quit();
    }
}

...或者稍微简化一下:

extern "C" void on_window_main_destroy()
{
    gtk_main_quit();
}

您也可以在这里走捷径,只需将 Builder 文件中的回调设置为 gtk_main_quit。通过这样做,您可以完全避免创建自己的功能。