当我使用 Glade 运行 GTK 时,我收到以下警告 - 找不到信号处理程序"on_window_main_destory"。您是否使用 -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

运行时,我收到以下警告-

找不到信号处理程序"on_window_main_destory"。你用-rdnamic编译了吗?

GTK Builder的设计并不是为了与C++或其他语言中的信号回调接口;C++函数被称为名称损坏,这意味着特定函数的真实名称可能与源代码中给出的函数名称截然不同。on_window_main_destroy函数实际上可能有一个类似于_Zxl65Abvon_window_main_destroyxxj的名称,这取决于所使用的编译器。这种篡改是为了对函数的名称空间、参数类型和返回值等进行编码,这样重载就可以工作了——也就是说,这样你就可以有两个或多个不同的函数,它们看起来同名,但接受或返回不同的参数。

因此,我真的建议在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即可。通过这样做,您可以完全避免创建自己的功能。

最新更新