1

我使用最近的 Glade 开发了一个应用程序,因此我需要它在运行时使用 GtkBuilder 从 XML 加载 UI。如果我尝试在 Gtk 太旧的发行版(例如 RHEL 5)上运行它,它将像这样失败

未定义符号:gtk_builder_new

这是正常和预期的。但我想知道是否有办法捕捉该错误,而是显示一个 GUI 错误对话框,上面写着“你的 Gtk 版本不够新”?这是在我的 main() 启动之前发生的错误,所以真正的问题是,有没有办法处理运行时链接错误?在谷歌搜索时,我发现提到了链接器插件的概念,但我还没有找到有关它的详细信息。这听起来像是无论如何都必须存在于我的应用程序之外的东西,所以也许这有点远。

我可以使用 dlopen() 来加载 Gtk,但这太荒谬了,因为我必须给出完整的路径,然后我必须调用 dlsym() 很多来链接我需要的每个函数。ld-linux.so 会搜索我。有没有办法我可以使用 ld-linux.so 告诉我 libgtk 的路径而不实际加载它,然后我检查版本是否足够新(或者只是 gtk_builder_new 是否存在),然后如果它可以完成运行时链接?

4

3 回答 3

1

您似乎在谈论您已针对具有足够新版本的标头进行编译但在您的库不够新的系统上运行的情况。

GTK 提供了一种工具来检查您是否已链接到足够新版本的库。例如,如果您至少需要 GTK 2.12(这是引入 GtkBuilder 的版本),您可以使用这段代码,它甚至会显示一个漂亮的 GUI 错误对话框:

if (gtk_major_version < 2 || gtk_minor_version < 12) {
    GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
        GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
        "Your version of GTK is too old to run this program.");
    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
        "You need at least version 2.12.0; your version is %d.%d.%d.",
        gtk_major_version, gtk_minor_version, gtk_micro_version);
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
    exit(-1);
}
于 2011-03-30T20:10:28.463 回答
1

好吧,它在 Linux 发行版上不起作用。你基本上在做的是绕过包管理器。

好的方法是在目标发行版上构建您的软件。在配置时(调用 ./configure),您将看到使用您的软件的要求没有得到满足。或者如果你没有配置脚本,编译器会在链接时大喊大叫。

然后,打包人员的工作就是填写包裹的要求。如果在 RPM 包的 .spec 文件中需要 gtk >= 2.16,那么在安装时,用户将看到一个对话框,告诉他缺少一些依赖项,他会看到他的 GTK 版本太旧。

于 2011-03-30T15:00:20.800 回答
0

这是一个可能有帮助的解决方法:重命名您的 exe 并创建一个调用它的 bash 脚本。

现在你可以这样做:

 EXE=...name-of-your-real-executable...
 LOG=logfile

 $EXE > "$LOG" 2>&1 || {
     if grep "undefined symbol: gtk_builder_new" "$LOG" ; then
         ... show error message ...
     fi
 }

[编辑]gtk_builder_new或者,您可以创建一个非常小的测试程序,它只包含在安装期间或在测试脚本中的调用并运行它。

这样,您就不需要检查特定的错误消息(可能会在非英语系统上翻译)。如果这个小测试程序失败,您可以确定是因为缺少这个符号而不是其他原因。

于 2011-03-30T08:23:07.070 回答