【问题标题】:Unresolved external symbols building a python C extension with swig against a shared C library未解决的外部符号使用 swig 针对共享 C 库构建 python C 扩展
【发布时间】:2014-07-17 13:16:47
【问题描述】:

我正在尝试使用 SWIG 为 python 包装一个 C 库。我在使用标准系统工具链的 linux 64 位系统(Gentoo)上。该库(SUNDIALS)安装在我的系统上,共享库位于/usr/local/lib

我的接口文件很简单(开始)

%module nvecserial

%{
#include "sundials/sundials_config.h"
#include "sundials/sundials_types.h"
#include "sundials/sundials_nvector.h"
#include "nvector/nvector_serial.h"
%}

%include "sundials/sundials_config.h"
%include "sundials/sundials_types.h"
%include "sundials/sundials_nvector.h"
%include "nvector/nvector_serial.h"

给定上面的接口文件,我运行

$ swig -python -I/usr/local/include nvecserial.i 
$ gcc -O2 -fPIC -I/usr/include/python2.7 -c nvecserial_wrap.c
$ gcc -shared /usr/local/lib/libsundials_nvecserial.so nvecserial_wrap.o -o _nvecserial.so
$ python -c "import nvecserial"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "nvecserial.py", line 28, in <module>
    _nvecserial = swig_import_helper()
  File "nvecserial.py", line 24, in swig_import_helper
    _mod = imp.load_module('_nvecserial', fp, pathname, description)
ImportError: ./_nvecserial.so: undefined symbol: N_VLinearSum

稍微挖掘以仔细检查显示

$ objdump -t /usr/local/lib/libsundials_nvecserial.so |grep Linear
0000000000001cf0 g     F .text  00000000000002e4              N_VLinearSum_Serial
$ objdump -t _nvecserial.so |grep Linear
00000000000097e0 l     F .text  0000000000000234              _wrap_N_VLinearSum
000000000000cd10 l     F .text  0000000000000234              _wrap_N_VLinearSum_Serial
0000000000000000         *UND*  0000000000000000              N_VLinearSum
0000000000000000       F *UND*  0000000000000000              N_VLinearSum_Serial

据我所知,N_VLinearSum 是围绕 N_VLinearSum_Serial 的包装器(也有并行实现,因此推测 nvecparallel 中的 N_VLinearSum 将包装 N_VLinearSum_Parallel)。我迷路的地方是下一步该做什么。这是我的接口定义有问题,还是我的编译有问题?

【问题讨论】:

    标签: python c swig


    【解决方案1】:

    我们将通过链接一个额外的库来让它工作。 libsundials_nvecserial.so 和 brethren 似乎不包含符号 N_VLinearSum。 SUNDIALS 制作过程将sundials_nvector.h 中的函数和符号放入不同的.so 文件中,这有点违反直觉。

    目前,我正在使用它

    $ gcc -shared -L/usr/local/lib nvecserial_wrap.o -o _nvecserial.so\
    -lsundials_nvecserial -lsundials_cvode
    $ python -c "import nvecserial"
    $
    

    我将继续使用源代码分发中的实际 .o 文件,但考虑到最终使用 distutils 分发包装模块的意图,并且不是每个人都可以访问其系统上的 SUNDIALS 源代码,我将可能会坚持在额外的共享库中进行链接。

    【讨论】:

    • 只是为了仔细检查,我再次尝试使用“错误”顺序的链接,即gcc -shared -L/usr/local/lib -lsundials_nvecserial -lsundials_cvode nvecserial_wrap.o -o _nvecserial.so。它奏效了,所以@Scholli 的建议不是问题,但仍然感谢。
    【解决方案2】:

    代替

    gcc -shared /usr/local/lib/libsundials_nvecserial.so nvecserial_wrap.o -o _nvecserial.so
    

    试试

    gcc -shared -L/usr/local/lib nvecserial_wrap.o -o _nvecserial.so -lsundials_nvecserial
    

    -l 应该放在末尾,否则可能无法在 lib 中搜索符号。这在 ld 手册页中有解释。

    【讨论】:

    • 谢谢,我试过了,但我仍然得到相同的结果。链接没有失败,至少没有错误消息。
    • @sirlark 可能是因为我的顺序不对,现在试试吧。
    • 谢谢,我也尝试了新订单,但也没有骰子。如果我查看 objdump 输出,则 N_VLinearSum 在被链接的两个库中都是 UND (未定义?未声明?)。除了查看 sundial_nvector.c 的 .c 源,它是完全定义的(不是外部或前向引用或任何东西)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2023-03-05
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多