【问题标题】:Undefined symbol when loading shared library in Python在 Python 中加载共享库时未定义的符号
【发布时间】:2016-12-05 11:58:29
【问题描述】:

我尝试在一些 python 代码中使用用 C++ 编写的共享库。我在Linux操作系统下。

首先我使用以下命令创建共享库:

g++ -Wall -fPIC -O2 -c HeliosDacAPI.cpp
g++ -shared -o libHeliosDacAPI.so HeliosDacAPI.o

然后我尝试在 python 控制台中加载这个库:

>>> import ctypes
>>> HeliosLib = ctypes.cdll.LoadLibrary("./libHeliosDacAPI.so")

我收到一个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/ctypes/__init__.py", line 425, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python3.5/ctypes/__init__.py", line 347, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: ./libHeliosDacAPI.so: undefined symbol: _ZN9HeliosDac18GetControlResponseEiPhi

这里是HeliosDacAPI.h

nm libHeliosDacAPI.so 显示:

0000000000202088 B __bss_start
0000000000202088 b completed.7585
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000202090 B dacController
0000000000000cb0 t deregister_tm_clones
0000000000000d40 t __do_global_dtors_aux
0000000000201dd8 t __do_global_dtors_aux_fini_array_entry
0000000000202078 d __dso_handle
0000000000202080 d DW.ref.__gxx_personality_v0
0000000000201de8 d _DYNAMIC
0000000000202088 D _edata
00000000002020a0 B _end
00000000000014b8 T _fini
0000000000000d80 t frame_dummy
0000000000201dd0 t __frame_dummy_init_array_entry
0000000000001758 r __FRAME_END__
0000000000202000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000014dc r __GNU_EH_FRAME_HDR
                 U __gxx_personality_v0@@CXXABI_1.3
0000000000000bb0 T _init
0000000000202098 B inited
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000201de0 d __JCR_END__
0000000000201de0 d __JCR_LIST__
                 w _Jv_RegisterClasses
                 U __printf_chk@@GLIBC_2.3.4
0000000000000cf0 t register_tm_clones
                 U __stack_chk_fail@@GLIBC_2.4
0000000000202088 d __TMC_END__
                 U _Unwind_Resume@@GCC_3.0
0000000000001230 T _Z10SetShutterib
0000000000000db0 T _Z10WriteFrameiihP11HeliosPointi
0000000000001420 T _Z11OpenDevicesv
00000000000013d0 T _Z12CloseDevicesv
0000000000001360 T _Z13EraseFirmwarei
0000000000001290 T _Z18GetFirmwareVersioni
0000000000000f20 T _Z4Stopi
0000000000000f90 T _Z7GetNameiPc
00000000000010c0 T _Z7SetNameiPc
0000000000001150 T _Z9GetStatusi
                 U _ZdlPv@@GLIBCXX_3.4
                 U _ZN9HeliosDac11OpenDevicesEv
                 U _ZN9HeliosDac11SendControlEiPhi
                 U _ZN9HeliosDac18GetControlResponseEiPhi
                 U _ZN9HeliosDac9SendFrameEiPhi
                 U _ZN9HeliosDacC1Ev
                 U _ZN9HeliosDacD1Ev
                 U _Znwm@@GLIBCXX_3.4

我正在寻找一些关于如何调试此类问题的提示。

【问题讨论】:

    标签: python c++ linker shared-libraries .so


    【解决方案1】:

    我不能确定,但​​似乎 HeliosDac::GetControlResponse(int, ?*, int) 是在 HeliosDac.cpp 中定义的,您没有编译并链接到 libHeliosDacAPI.so。

    确实,从nm libHeliosDacAPI.so 我们清楚地看到使用了这个符号,但是Undefined(这意味着您的问题不是来自您从python 加载库的方式):

                     U _ZN9HeliosDac18GetControlResponseEiPhi
    

    你可以尝试编译:

    g++ -Wall -fPIC -O2 -c HeliosDacAPI.cpp
    g++ -Wall -fPIC -O2 -c HeliosDac.cpp
    g++ -shared -lusb -o libHeliosDacAPI.so HeliosDacAPI.o HeliosDac.o
    

    【讨论】:

    • 您能否详细说明实际问题,或链接到具有更多信息的某个地方?我有一个相关的“未定义符号”问题,但我找不到一种方法来概括这个答案。在这里发布这个是因为这个页面显示在顶部谷歌搜索“python加载库未定义符号”的变体。
    • @JaccovanDorp 给你:stackoverflow.com/q/12573816/5470596
    • 所以,如果我没弄错的话,要么是您缺少另一个共享对象/DLL,要么是共享对象/DLL 编译不正确。明白了。
    猜你喜欢
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2016-10-16
    相关资源
    最近更新 更多