GTK C++:找不到信号处理程序是否使用 -rdynamic 进行编译?
GTK C++: Could not find signal handler Did you compile with -rdynamic?
我是 GTK 编程的新手,我面临以下问题。我可以在没有任何警告或错误的情况下编译代码,但是当我执行二进制文件时,我得到了这个提示并且按钮不起作用。
错误如下所示:
(项目:9686):Gtk-警告 **:16:26:31.359:找不到信号处理程序 'on_button_clicked'。您是否使用 -rdynamic 进行编译?
也就是代码:
#include <gtk/gtk.h>
static const gchar *interface =
"<interface>"
" <object class=\"GtkWindow\" id=\"main-window\">"
" <signal name=\"destroy\" handler=\"gtk_main_quit\"/>"
" <child>"
" <object class=\"GtkButton\" id=\"my-button\">"
" <property name=\"label\">Hallo, Welt!</property>"
" <signal name=\"clicked\" handler=\"on_button_clicked\"/>"
" </object>"
" </child>"
" </object>"
"</interface>";
G_MODULE_EXPORT void on_button_clicked (GtkWidget *w, gpointer d)
{
g_print ("Hallo, Welt!\n");
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *window;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, interface, -1, &error);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET(gtk_builder_get_object (builder, "main-window"));
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
我在 Linux 机器上工作,我在终端中使用以下命令编译:
g++ -Wall -std=c++0x project.cpp `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0` -o project
我尝试编译:
- -rdynamic
- -Wl,--export-dynamic
- -lgmodule-2.0
pkg-config --cflags --libs gtk+-3.0 gmodule-no-export-2.0
但没有任何效果。
很难确定,但我猜问题是您正在使用 C++ 编译器进行编译,而您的示例是用 C 编写的。C++ 编译器是 "mangling" 您导出的符号的名称.如果您不使用 C++ 编写程序的其余部分,那么我建议使用 gcc -std=c99
而不是 g++ -std=c++0x
.
进行编译
另一方面,如果您的程序的其余部分确实需要用 C++ 编写,那么您将需要为要为 GtkBuilder 导出的每个符号添加前缀(它不知道 C++ name mangling ) 和 extern "C"
,或者将它们一起放在一个或多个 extern "C" { ... }
块中。这将防止名称被破坏,因此 GtkBuilder 将能够找到它。
要检查是否是这种情况,请在您的编译文件上尝试 运行 nm -g | grep on_button_clicked
(没有任何 "demangle" 选项)。如果名称被损坏,您将看到类似 __Z17on_button_clicked13BLAH14BLAH
的内容,而如果不是,则您只会看到 _on_button_clicked
.
我是 GTK 编程的新手,我面临以下问题。我可以在没有任何警告或错误的情况下编译代码,但是当我执行二进制文件时,我得到了这个提示并且按钮不起作用。 错误如下所示:
(项目:9686):Gtk-警告 **:16:26:31.359:找不到信号处理程序 'on_button_clicked'。您是否使用 -rdynamic 进行编译?
也就是代码:
#include <gtk/gtk.h>
static const gchar *interface =
"<interface>"
" <object class=\"GtkWindow\" id=\"main-window\">"
" <signal name=\"destroy\" handler=\"gtk_main_quit\"/>"
" <child>"
" <object class=\"GtkButton\" id=\"my-button\">"
" <property name=\"label\">Hallo, Welt!</property>"
" <signal name=\"clicked\" handler=\"on_button_clicked\"/>"
" </object>"
" </child>"
" </object>"
"</interface>";
G_MODULE_EXPORT void on_button_clicked (GtkWidget *w, gpointer d)
{
g_print ("Hallo, Welt!\n");
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *window;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, interface, -1, &error);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET(gtk_builder_get_object (builder, "main-window"));
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
我在 Linux 机器上工作,我在终端中使用以下命令编译:
g++ -Wall -std=c++0x project.cpp `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0` -o project
我尝试编译:
- -rdynamic
- -Wl,--export-dynamic
- -lgmodule-2.0
pkg-config --cflags --libs gtk+-3.0 gmodule-no-export-2.0
但没有任何效果。
很难确定,但我猜问题是您正在使用 C++ 编译器进行编译,而您的示例是用 C 编写的。C++ 编译器是 "mangling" 您导出的符号的名称.如果您不使用 C++ 编写程序的其余部分,那么我建议使用 gcc -std=c99
而不是 g++ -std=c++0x
.
另一方面,如果您的程序的其余部分确实需要用 C++ 编写,那么您将需要为要为 GtkBuilder 导出的每个符号添加前缀(它不知道 C++ name mangling ) 和 extern "C"
,或者将它们一起放在一个或多个 extern "C" { ... }
块中。这将防止名称被破坏,因此 GtkBuilder 将能够找到它。
要检查是否是这种情况,请在您的编译文件上尝试 运行 nm -g | grep on_button_clicked
(没有任何 "demangle" 选项)。如果名称被损坏,您将看到类似 __Z17on_button_clicked13BLAH14BLAH
的内容,而如果不是,则您只会看到 _on_button_clicked
.