ski*_*ell 11 c++ python numpy python-embedding python-3.x
我正在运行一个C++应用程序,它尝试使用https://docs.python.org/3.5/extending/embedding.html函数调用来运行python .这是应用程序错误消息管道给我的错误.
class'ImportError':导入多阵列numpy扩展模块失败.您很可能正在尝试导入失败的numpy版本.如果您正在使用numpy git repo,请尝试
git clean -xdf(删除不受版本控制的所有文件).否则重新安装numpy.原始错误是:/usr/local/lib/python3.5/site-packages/numpy/core/multiarray.cpython-35m-x86_64-linux-gnu.so:undefined symbol:PyExc_UserWarning
我很困惑,因为只有当我在C++中嵌入Python时才会出现这种情况,因为当我通过解释器使用它时导入工作.我对答案更感兴趣,这个答案增加了我的理解,而不是快速做到这一点或做了那个修复.我列出了下面的一些系统/问题信息,以及我正在考虑发布关于同一主题的一些其他问题.任何指导表示赞赏!
系统/问题信息:
import sys,sys.pathPy_Import_Import(),Py_Initialize()(我确信它只能调用一次.)等,但它并没有得到解释的全局锁.pip3.5 install numpy命令使用pip 9.0.0安装numpy-1.14.2import numpy...ldd on multiarray.cpython-35m-x86_64-linux-gnu.so显示:
ldd multiarray.cpython-35m-x86_64-linux-gnu.so
linux-vdso.so.1 =>(0x00007ffd9e36b000)
libopenblasp-r0-39a31c03.2.18.so => /usr/local/lib/python3.5/site-packages/numpy/core/./../.libs/libopenblasp-r0-39a31c03.2.18.so(0x00007fdbe149b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6(0x00007fdbe1192000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0(0x00007fdbe0f75000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007fdbe0bab000)/ lib64 /ld-linux-x86-64.so.2(0x00007fdbe3ed5000)
libgfortran-ed201abd.so.3.0.0 => /usr/local/lib/python3.5/site-packages/numpy/core/./../.libs/libgfortran-ed201abd.so.3.0.0(0x00007fdbe08b1000)
我可以/可能会尝试通过不同的方式重新安装numpy,但我无法跟踪为什么这可能会起作用.
在这一点上,我假设我的知识存在一些漏洞.我已经看过很多关于在C++中嵌入Python时无法导入多阵列组件和numpy的类似帖子; 但是,要么它们都不符合我的具体情况,要么就像我说的那样存在漏洞.以下是我可能会问的一个子问题列表,如果没有人在这个设置中看到任何明显有关的内容.如果我问他们(在我擦亮之后),我可能会用链接更新问题.
在这一点上,我不是要求上述问题清单的答案,而是我提供更多线索,知道我的知识差距.
感谢您抽出时间阅读这个问题.任何帮助表示赞赏.
好吧,我找到了一个工作,我正在使用它.Dunes问题开始让我更仔细地思考未定义的符号以及它如何成为链接器/编译器错误,或者numpy导入总是期望具有已经加载到内存中的符号的环境.这让我试图安装不同版本的numpy,看看是否有任何旧版本有所作为.他们没有,但它确实使错误略有不同.当我用Google搜索时,出现了这个问题.接受的答案通过将这两行添加到pythonInterface.cpp中给了我一个解决方法:
#include <dlfcn.h>dlopen("libpython3.5m.so.1.0", RTLD_LAZY | RTLD_GLOBAL)这些命令添加要加载的共享库,并可用于cpython.multiarray.so.
这不是一个理想的解决方案,因为它指向一个特定的.so,它可能因机器而异.它解决了这个问题,但是如果pythonInterface.so的链接库发生了变化,并且这行不会更新,那么它也可能导致错误,在python调用过程中可能会出现共享库不匹配的问题.如果这个子问题得到解答,我相信可以获得更好的答案,所以我目前一直坚持提交或接受答案.谢谢!
根本原因
发生此错误是因为multiarray.cpython-35m-x86_64-linux-gnu.sonumpy 中的模块依赖于libpythonx.x.so,无论是不是显式链接libpythonx.x.so. 因此,如果您使用,ldd -d multiarray.cpython-35m-x86_64-linux-gnu.so您将不会在列表中看到 python。
Python 没有问题,因为 python 二进制文件依赖于libpython.x.x.so,所以当 numpymultiarray.cpython-35m-x86_64-linux-gnu.so使用dlopen. libdl.so将尝试通过检查主程序 python 的依赖共享库来解析未定义的符号。它会在libpython.x.x.so.
解决方案
知道根本原因后,解决方案很容易,只需帮助libdl.so就能找到libpython.x.x.so。至少有两种方法可以实现:
dlopen("libpythonx.x.so", RTLD_GLOBAL). 打开这个 so useRTLD_GLOBAL标志后,它使 libpythonx.x.so 中的符号可用于随后加载的共享对象的符号解析。libpythonx.x.so其添加到其依赖库中。| 归档时间: |
|
| 查看次数: |
817 次 |
| 最近记录: |