git clean -xdf
(删除所有未受版本控制的文件)。否则重新安装numpy。
原始错误是:/usr/local/lib/python3.5/site-packages/numpy/core/multiarray.cpython-35m-x86_64-linux-gnu.so:未定义的符号:PyExc_UserWarning我感到困惑,因为只有在将Python嵌入C++中时才会出现此问题,而当我通过解释器使用它时,导入工作正常。我更感兴趣的是能够增加我的理解而不是快速解决此问题。我列出了一些系统/问题信息以及我正在考虑发布有关同一主题的其他问题。感谢任何指导!
- Ubuntu 16.04, 64位
- 编译Python 3.5.5并启用shared
- numpy在解释器(python3.exe和python3.5.exe)中可导入
- 我确保PySys_SetPath()设置的sys.path与解释器输出的相同:
import sys
,sys.path
- 我可以导入其他模块,如PIL和datetimeutil;但是,无法导入numpy和pandas(pandas使用numpy或似乎是这样)
- 嵌入式Python使用以下命令:
Py_Import_Import()
,Py_Initialize()
(我确定只调用了一次)。等等,但它没有在解释器上获取全局锁。 - 该应用程序使用CMake构建系统构建,该系统编译为我的系统的MakeFiles。
- 使用pip 9.0.0使用
pip3.5 install numpy
命令安装了numpy-1.14.2 - 引起此错误的Python脚本只有一行:
import numpy
... - 我没有从中导入文件的.zip文件。
- 嵌入在C++中的Python使用的.exe位于/usr/local/bin/python3(使用Py_GetProgramName()确定此)。这个.exe链接到libpython3.5m.so.1.0,缺少的符号位于libpython3.5m.so.1.0中(运行nm)
multiarray.cpython-35m-x86_64-linux-gnu.so的ldd显示:
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 multiarray.so如何链接到pythonX.X.so以进行符号解析?ldd似乎并没有表明它曾经这样做过。在link上提出了这个问题
- CMake问题非相关问题已在question上解决,该问题于4/12/18提出,4/16/18回答。
- 在.bashrc中设置PYTHONPATH似乎不能更新Py_GetPath()返回的内容,我必须通过其他方法添加site-packages以使其能够通过sys.path进行导入。它可能只更新bash脚本环境变量,而不影响C++。
编辑:2018年4月17日:
好的,我找到了一种解决方法,并正在使用它。Dunes的问题让我更加密切地思考未定义符号以及它可能是链接器/编译器错误,或者numpy导入始终期望已将这些符号加载到内存中的环境。这使我尝试安装不同版本的numpy,看看是否有任何旧版本有所不同。它们没有,但确实使错误抛出略有不同。当我谷歌搜索时,出现了这个问题。接受的答案通过将以下两行添加到pythonInterface.cpp中为我提供了解决方法:
#include <dlfcn.h>
dlopen("libpython3.5m.so.1.0", RTLD_LAZY | RTLD_GLOBAL)
这些命令将共享库添加到加载并可用于cpython.multiarray.so中。
这并不是一个理想的解决方案,因为指向特定的.so文件可能会因机器而异。虽然它暂时解决了问题,但在Python调用过程中,如果链接到pythonInterface.so的共享库发生更改,而此行未更新,则可能导致共享库不匹配的错误。我认为,如果回答了sub-question,就可以得到更好的答案,因此我目前还没有提交或接受答案。谢谢!
PyRun_SimpleString
来导入numpy,创建一个数组,进行算术运算并打印输出。我还尝试直接导入numpy.core.multiarray
。 - Dunes