kat*_*z77 4 python boost numpy cmake
我在共享库插件中使用 boost::python 来运行一些 python 代码。我的主程序使用 boost::dll::shared_library API 在运行时将共享库作为插件加载。即我的主程序没有与共享库插件链接。我的代码在 Ubuntu 20.04 上运行。
我将我的共享库与 Python 链接:
my_shared_lib/CMakeLists.txt:
find_package(Python3 COMPONENTS Development NumPy REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ${Python3_LIBRARIES} Python3::NumPy)
Run Code Online (Sandbox Code Playgroud)
当从我的共享库运行以下代码时,我收到导入错误:
#include <boost/python.hpp>
Py_Initialize();
namespace np = boost::python::numpy;
np::initialize(); //ImportError here
Run Code Online (Sandbox Code Playgroud)
我收到以下错误: ImportError:/home/myuser/.local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-x86_64-linux-gnu.so:未定义符号:PyObject_SelfIter
我验证了我的 LD_LIBRARY_PATH 上有 /usr/lib/x86_64-linux-gnu/libpython3.8.so 。
当我的主程序与 Python 链接时,程序正常运行,没有 ImportError main_program/CMakeLists.txt:
find_package(Python3 COMPONENTS Development NumPy REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ${Python3_LIBRARIES} Python3::NumPy)
Run Code Online (Sandbox Code Playgroud)
我这里的结论是,在运行时加载共享库插件似乎没有加载libpython3.8.so,而在主程序中加载libpython3.8.so使其可供共享库插件使用。
如果我像这样在共享库中手动加载 libpython3.8.so
#include <boost/python.hpp>
#include <dlfcn.h>
dlopen("/usr/lib/x86_64-linux-gnu/libpython3.8.so", RTLD_LAZY | RTLD_GLOBAL);
Py_Initialize();
namespace np = boost::python::numpy;
np::initialize();
Run Code Online (Sandbox Code Playgroud)
在此过程中,我进一步遇到了不同的错误:
Traceback(最近一次调用最后):文件“/home/myuser/.local/lib/python3.8/site-packages/numpy/core/ init .py”,第23行,在从. 导入多数组文件“/home/myuser/.local/lib/python3.8/site-packages/numpy/core/multiarray.py”,第 10 行,来自 . 导入覆盖文件“/home/myuser/.local/lib/python3.8/site-packages/numpy/core/overrides.py”,第 6 行,来自 numpy.core._multiarray_umath import ( ImportError: PyCapsule_Import 无法导入模块“约会时间”
如何让我的共享库插件在加载时自动加载 libpython3.8.so?
*** 编辑 ***
使用 gdb 我发现我最初的假设是错误的。当主应用程序加载我的共享库插件时,它还会加载 libpython3.8.so.1.0。已加载已加载'/home/myuser/.vs/mainapp/build/plugins/libap_python_ detector.so'。符号已加载。已加载“/usr/local/3rdparty/hpc/5.13.0-39_AMD_EPYC/boost176/build/lib/libboost_numpy38.so.1.76.0”。符号已加载。已加载“/lib/x86_64-linux-gnu/libpython3.8.so.1.0”。符号已加载。已加载“/usr/local/3rdparty/hpc/5.13.0-39_AMD_EPYC/boost176/build/lib/libboost_python38.so.1.76.0”。符号已加载。
那么加载 numpy 出了什么问题呢?
目前,NumPy 不支持从嵌入共享库的 Python 解释器加载 NumPy 的设计。(请参阅对 ImportError 进行故障排除 。它不涵盖您的情况。)
发生错误的原因是 NumPy 共享库几乎没有链接到 Python 运行时库。(您可以使用ldd检查它。)
但至少在 Linux 上,您可以通过使用 RTLD_GLOBAL 标志手动加载 Python 运行时库来解决此问题,如下例所示。(在主程序中加载运行时库,而不是在插件中。当然,只有在加载依赖于 Numpy 的插件时才需要这样做。)
#include <dlfcn.h>
int main()
{
...
// When you load a NumPy-dependent plugin, do the following just before that.
dlopen("libpython3.8.so", RTLD_LAZY | RTLD_GLOBAL);
...
}
Run Code Online (Sandbox Code Playgroud)
但我不确定它将来不会被打破。
| 归档时间: |
|
| 查看次数: |
592 次 |
| 最近记录: |