C++ 导入.so时,导入语句的顺序是否重要?

C++ 导入.so时,导入语句的顺序是否重要?,c++,python,import,boost-python,shared-libraries,C++,Python,Import,Boost Python,Shared Libraries,在尝试加载使用boostpython编译的python模块时,我遇到以下导入错误 ImportError: /path/to/library/libxml2.so.2: symbol gzopen64, version ZLIB_1.2.3.3 not defined in file libz.so.1 with link time reference 奇怪的是,如果这是要导入的非标准模块,我没有看到这个错误。i、 e如果我导入其他模块,然后导入此模块,则导入失败并出现错误。不确定出了什么问题

在尝试加载使用boostpython编译的python模块时,我遇到以下导入错误

ImportError: /path/to/library/libxml2.so.2: symbol gzopen64, version ZLIB_1.2.3.3 not defined in file libz.so.1 with link time reference
奇怪的是,如果这是要导入的非标准模块,我没有看到这个错误。i、 e如果我导入其他模块,然后导入此模块,则导入失败并出现错误。不确定出了什么问题或如何调试

编辑: 要准确显示问题,请执行以下操作:

$ python -c 'import json, libMYBOOST_PY_LIB' # DOES NOT WORK!!!
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: path/to/xml_library/libxml2.so: symbol gzopen64, version ZLIB_1.2.3.3 not defined in file libz.so.1 with link time reference
$ python -c 'import libMYBOOST_PY_LIB, json' # WORKS NOW!!!
$
$python-c'导入json,libMYBOOST\u PY\u LIB'不起作用!!!
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ImportError:path/to/xml_library/libxml2.so:symbol gzopen64,版本ZLIB_1.2.3.3未在文件libz.so.1中定义,带有链接时间参考
$python-c‘导入libMYBOOST_PY_LIB,json’#现在可以工作了!!!
$

它不仅仅是json,当在我的模块之前导入时,很少有其他模块也会导致相同的问题。urllib2导入语句的顺序很重要

:

一旦知道模块的名称(除非另有规定,否则术语“模块”将同时指包和模块),就可以开始搜索模块或包。选中的第一个位置是
sys.modules
,它是以前导入的所有模块的缓存。如果在那里找到该模块,则在导入的步骤(2)中使用该模块

任何模块都可以更改:

  • -以前导入的所有模块的缓存
  • -模块的搜索路径
他们还可以更改导入挂钩:

导入挂钩可以让您从zip文件、任何类型的存档文件、网络等加载模块


此语句肯定会修改sys.modules,将其依赖项加载到模块缓存中。它也可以修改系统路径。实际上,框架(例如,
boost
zope
django
请求
…)通常附带电池/所依赖模块的副本

  • django
    附带
    json
  • 请求
    urllib3一起提供
要准确查看库将加载的内容,您可以使用:

python -v -c 'import libMYBOOST_PY_LIB'
问题 问题在于操作系统。Linux库(动态链接的共享对象库)可以依赖于其他库(也可以依赖于其他库等等)。如果未正确解析这些依赖库,则会出现所描述的错误

什么是共享库(so) 通过获取多个对象文件并将它们链接在一起,可以创建共享库。创建共享库时,链接器会保留大量元数据:

  • 搬家桌
  • 导出符号(其他人可以访问的函数和变量)的列表
  • 导入符号的列表(此库从其他库使用的函数和变量)
  • 其他库的文件名列表,可用于满足导入的符号
  • 使用库时,系统将加载库,更改重定位表引用的地址,然后尝试查找导入的符号。为此,系统首先检查已加载的库。如果不满足所有符号,它将尝试查找库中列出的文件名,并检查是否存在具有该名称的文件,该文件是否为有效库,以及是否导出所需的符号

    通常这里的“系统”是动态加载程序,它在用户空间中运行,而不是在内核空间中运行

    如何检查程序使用了哪些库 您可以使用ldd检查库的内容

    如果要检查正在运行的可执行文件,请尝试
    lsof
    并筛选
    *。因此
    并检查
    /proc/[pid]/maps

    如何调试您的问题 在您的情况下,在加载相关库之前直接按住程序(例如,从控制台插入读取或sleep命令)。然后检查当前加载的库。您会发现,在良好的情况下,已经加载了一个库,用于导出所讨论的符号。在错误情况下,未加载该库,系统将在下一步尝试加载错误的依赖库(例如,库的不同版本,其中缺少所需的符号)

    图书馆的秩序重要吗
    通常不会,但这取决于细节。当不同版本中需要相同的库时,或者当系统无法在所有情况下解析共享库时,它可能变得很重要。不幸的是,这些问题很难调试。在Windows上有DLL地狱,在Linux上与共享对象类似。祝你好运调试你的问题

    通过从json和libMYBOOST_PY_LIB导入libz是否存在版本冲突,这由导入顺序(获取最新版本)解决?
    ldd/path/to/_json。因此
    没有
    libz.so
    作为依赖项。我检查对了吗?可能您需要展示如何编译和生成libMYBOOST_PY_库,比如g++命令。它可以提示您如何链接libxml库。在Ubuntu中执行:ldd/usr/lib/x86_64-linux-gnu/libjson-glib-1.0.so.0.1502.0显示libz.so.1=>/lib/x86_64-linux-gnu/libz.so.1(0x00007fd6f1892000)
    python -v -c 'import libMYBOOST_PY_LIB'