我在共享库插件中使用boost::python运行一些python代码。共享库由我的主程序使用boost::dll::shared_library API在运行时作为插件加载。也就是说,我的主程序不与共享库插件链接。我的代码运行在Ubuntu20.04上。
我将共享库链接到Python:
my_shared_lib/CMakeLists.txt:
find_package(Python3 COMPONENTS Development NumPy REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ${Python3_LIBRARIES} Python3::NumPy)
当从我的共享库运行以下代码时,我会得到一个ImportError:
#include <boost/python.hpp>
Py_Initialize();
namespace np = boost::python::numpy;
np::initialize(); //ImportError here
我得到以下错误: ImportError: ImportError未定义符号: PyObject_SelfIter
我验证了我的LD_LIBRARY_PATH上有/usr/lib/x86_64-linux-gnu/libpython3.8。
当我的主程序与Python链接时,程序OK运行w/o -- ImportError main_ program /CMakeLists.txt:
find_package(Python3 COMPONENTS Development NumPy REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ${Python3_LIBRARIES} Python3::NumPy)
我在这里的结论是,在运行时加载共享库插件似乎没有加载libpython3.8.so,而在主程序中加载libpython3.8.so使它可以用于共享库插件。
如果我手动加载library 3.8,那么在我的共享库中,如下所示
#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();
在这一过程中,我得到了一个不同的错误:
回溯(最近一次调用):文件"/home/myuser/.local/lib/python3.8/site-packages/numpy/core/init.py",第23行,in from。导入多数组文件"/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导入( ImportError: PyCapsule_Import无法导入模块“日期时间”)
如何在加载共享库插件时自动加载libpython3.8.so 3.8?
编辑*
使用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/libpython3.8.so.1.0’。符号已加载。加载'/usr/local/3rdparty/hpc/5.13.0-39_AMD_EPYC/boost176/build/lib/libboost_python38.so.1.76.0'.符号已加载。
装泡泡有什么不对?
发布于 2022-08-02 12:24:03
目前,从嵌入在共享库中的Python解释器加载NumPy的设计不受NumPy支持(参见Troubleshooting ImportError )。它不包括您的场景。)
发生此错误是因为NumPy共享库几乎没有链接到运行时库。(您可以使用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);
...
}
但我不确定它将来会不会被打破。
https://stackoverflow.com/questions/73205684
复制相似问题