【问题标题】:How can I fix 'undefined symbol' in a shared library created by CFFI?如何修复 CFFI 创建的共享库中的“未定义符号”?
【发布时间】:2020-04-13 02:01:29
【问题描述】:

我编写了一个 C 程序来使用 GStreamer 和 GTK 窗口显示内存映射的视频文件。目的是用 CFFI 构建一个可以从 Python 调用的共享库。当我尝试导入库时,我收到一条报告未定义符号的消息。

我用一个包含一个只显示一个窗口的小程序的库重新创建了这个问题:

#include <gtk/gtk.h>
#include "test_cdef.h"

int main (int argc, char *argv[])
{
  return test();
}

int test()
{
  GtkWidget  *main_window;
  gtk_init (NULL, NULL);
  main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(main_window), "Test");
  gtk_window_set_default_size(GTK_WINDOW(main_window), 1600, 900);
  gtk_widget_show_all(main_window);
  g_main_loop_run (g_main_loop_new (NULL, TRUE));
  return 0;
}

当我尝试导入库时,我收到以下消息:

ImportError: [library file name]: undefined symbol: gtk_window_get_type

经过大量搜索,似乎最接近我的问题已通过更改编译器/链接选项得到解决。我使用 gcc 来构建程序。我假设 CFFI 使用相同的方法来构建库。

如果应该更改这些选项,我会有两个问题:(1) 应该使用哪些选项,以及 (2) 这些选项如何传达给 CFFI?对于任何一个问题,我都将不胜感激。

我的操作系统是 Linux Mint 19.3。其他包有 GTK-3.0、python 3.6.9、python3-cffi 1.11.5-1。

任何帮助将不胜感激。

【问题讨论】:

    标签: python shared-libraries linker


    【解决方案1】:

    我找到了解决方案。这确实是两个不同级别的链接问题——构建静态库的链接和构建链接到静态库的共享库的链接。

    当我终于能够找到定义第一个报告的符号问题的 GTK 库的名称时,我的突破就来了。我将该库名称添加到我的 makefile 中命令的 gcc 链接部分。通过这一添加,链接器足以按名称报告另一个丢失的库 - 尽管错误消息有点神秘 - 称它为丢失的 DSO(动态共享对象)。为什么设计者没有编写链接器来报告遗漏并自动添加丢失的库是另一天的话题。一个一个地添加缺少的库,我最终能够构建一个没有错误的静态库。

    使用 CFFI,缺少的库在 [libraries] 列表中指定,它们的公共目录(我的系统上的 /usr/lib/x86_64-linix-gnu)在 [library-dirs] 列表中指定。共享库的构建又遇到了几个缺失的库,我最终通过搜索包含缺失符号的文本字符串的库文件找到了。

    【讨论】:

      猜你喜欢
      • 2016-10-16
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 2018-04-14
      • 2011-07-19
      相关资源
      最近更新 更多