开发者社区> 问答> 正文

嵌入在C ++中使用Numpy的Python在运行时动态加载的库中不起作用

我想通过动态加载的库(dlopen/dlsym)将Python嵌入到Ubuntu Linux中的C ++中。当我嵌入一个通过单个C ++静态链接的可执行文件导入numpy的Python模块时,一切正常。当我使用动态加载的库而不尝试导入numpy时,一切正常。但是,当我尝试从动态加载的库中导入numpy`时,它失败了。

*首先,这是一个没有动态库的简单示例 test_static.cpp #include #include <Python.h>

int main(){

  Py_Initialize();

  PyObject* pName = PyUnicode_FromString("mymodule");
  PyObject* pModule = PyImport_Import(pName);
  if (!pModule){
    std::cout << "PyImport_Import() failed for " << "test" << std::endl;
    PyErr_Print();
    exit(-1);
  }

  PyObject* pDict = PyModule_GetDict(pModule);
  if (!pDict){
    std::cout << "PyModule_GetDict() failed" << std::endl;
    exit(-1);
  }
  PyObject* pClass = PyDict_GetItemString(pDict,"myclass");

  if (!PyCallable_Check(pClass)) {
    std::cout << "PyCallable_Check(pClass) failed" << std::endl;
    exit(-1);
  }
  PyObject* pInstance = PyObject_CallObject(pClass, NULL);

  pName = PyUnicode_FromString("mymethod");
  PyObject* result=PyObject_CallMethodObjArgs(pInstance, pName,NULL);
  if (!result){
    std::cout << "Error calling PyObject_CallMethodObjArgs" << std::endl;
    PyErr_Print();
    exit(-1);
  }
  Py_DECREF(pName);
  Py_DECREF(pModule);
  Py_Finalize();

  return 0;
}

这是用

g ++ -g -O0 -o test_embed_python_static test_static.cpp -I / usr / include / python3.7m -lpython3.7m

我的Python模块是:

mymodule.py import numpy as np

class myclass:
  def __init__(self):
    self.something="asdf"
    self.a=np.zeros( (5),dtype=float)
  def mymethod(self):
    print("Called myclass.mymethod()")
    print('%d'%(self.a.size))

这个Python模块位于本地目录中,我设置了环境变量export PYTHONPATH =。

输出为:

user@host:~/test_embed_python$ ./test_embed_python_static
Called myclass.mymethod()
5

这是使用动态库的示例: test_dynamic.cpp #include <dlfcn.h> typedef void MyCppFunctionHandle(); int main(){ void soHandle = dlopen("/home/user/lib/libtestlib.so", RTLD_NOW ); MyCppFunctionHandle* functionHandle=(MyCppFunctionHandle*dlsym(soHandle,"MyCppFunction"); functionHandle(); return 0; } test_lib.cpp #include #include <Python.h>

extern "C"
void MyCppFunction(){

  Py_Initialize();

  PyObject* pName = PyUnicode_FromString("mymodule");
  PyObject* pModule = PyImport_Import(pName);
  if (!pModule){
    std::cout << "PyImport_Import() failed for " << "mymodule" << std::endl;
    PyErr_Print();
    exit(-1);
  }

  PyObject* pDict = PyModule_GetDict(pModule);
  if (!pDict){
    std::cout << "PyModule_GetDict() failed" << std::endl;
    exit(-1);
  }

  PyObject* pClass = PyDict_GetItemString(pDict,"myclass");

  if (!PyCallable_Check(pClass)) {
    std::cout << "PyCallable_Check(pClass) failed" << std::endl;
    exit(-1);
  }
  PyObject* pInstance = PyObject_CallObject(pClass, NULL);

  pName = PyUnicode_FromString("mymethod");
  PyObject* result=PyObject_CallMethodObjArgs(pInstance, pName,NULL);
  if (!result){
    std::cout << "Error calling PyObject_CallMethodObjArgs" << std::endl;
    PyErr_Print();
    exit(-1);
  }
  Py_DECREF(pName);
  Py_DECREF(pModule);
  Py_Finalize();
}

构建库和主要可执行文件:

g++ -g -O0 -fPIC -shared -o libtestlib.so test_lib.cpp -I/usr/include/python3.7m -lpython3.7m
mv libtestlib.so ~/lib/
g++ -g -O0 -o test_embed_python_dynamic test_dynamic.cpp -ldl

使用与上面相同的mymodule.py并将PYTHONPATH设置为`。再次。

输出:

user@host:~/test_embed_python$ ./test_embed_python_dynamic 
Dynamic library opened successfully
Function loaded successfully
Calling function
PyImport_Import() failed for mymodule
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/numpy/core/__init__.py", line 40, in <module>
    from . import multiarray
  File "/usr/lib/python3/dist-packages/numpy/core/multiarray.py", line 12, in <module>
    from . import overrides
  File "/usr/lib/python3/dist-packages/numpy/core/overrides.py", line 6, in <module>
    from numpy.core._multiarray_umath import (
ImportError: /usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so: undefined symbol: PyExc_ImportError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/code/test/test_embed_python/mymodule.py", line 1, in <module>
    import numpy as np
  File "/usr/lib/python3/dist-packages/numpy/__init__.py", line 142, in <module>
    from . import core
  File "/usr/lib/python3/dist-packages/numpy/core/__init__.py", line 71, in <module>
    raise ImportError(msg)
ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the multiarray numpy extension module failed.  Most
likely you are trying to import a failed build of numpy.
Here is how to proceed:
- If you're working with a numpy git repository, try  \` git clean -xdf \` 
  (removes all files not under version control) and rebuild numpy.
- If you are simply trying to use the numpy version that you have installed:
  your installation is broken - please reinstall numpy.
- If you have already reinstalled and that did not fix the problem, then:
  1. Check that you are using the Python you expect (you're using /usr/bin/python3),
     and that you have no directories in your PATH or PYTHONPATH that can
     interfere with the Python and numpy versions you're trying to use.
  2. If (1) looks fine, you can open a new issue at
     https://github.com/numpy/numpy/issues.  Please include details on:
     - how you installed Python
     - how you installed numpy
     - your operating system
     - whether or not you have multiple versions of Python installed
     - if you built from source, your compiler versions and ideally a build log

     Note: this error has many possible causes, so please don't comment on
     an existing issue about this - open a new one instead.

Original error was: /usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so: undefined symbol: PyExc_ImportError

Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
    from apport.fileutils import likely_packaged, get_recent_crashes
  File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
    from apport.report import Report
  File "/usr/lib/python3/dist-packages/apport/report.py", line 30, in <module>
    import apport.fileutils
  File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 23, in <module>
    from apport.packaging_impl import impl as packaging
  File "/usr/lib/python3/dist-packages/apport/packaging_impl.py", line 23, in <module>
    import apt
  File "/usr/lib/python3/dist-packages/apt/__init__.py", line 23, in <module>
    import apt_pkg
ImportError: /usr/lib/python3/dist-packages/apt_pkg.cpython-37m-x86_64-linux-gnu.so: undefined symbol: PyExc_ValueError

Original exception was:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/numpy/core/__init__.py", line 40, in <module>
    from . import multiarray
  File "/usr/lib/python3/dist-packages/numpy/core/multiarray.py", line 12, in <module>
    from . import overrides
  File "/usr/lib/python3/dist-packages/numpy/core/overrides.py", line 6, in <module>
    from numpy.core._multiarray_umath import (
ImportError: /usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so: undefined symbol: PyExc_ImportError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/test_embed_python/mymodule.py", line 1, in <module>
    import numpy as np
  File "/usr/lib/python3/dist-packages/numpy/__init__.py", line 142, in <module>
    from . import core
  File "/usr/lib/python3/dist-packages/numpy/core/__init__.py", line 71, in <module>
    raise ImportError(msg)
ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the multiarray numpy extension module failed.  Most
likely you are trying to import a failed build of numpy.
Here is how to proceed:
- If you're working with a numpy git repository, try  \` git clean -xdf \` 
  (removes all files not under version control) and rebuild numpy.
- If you are simply trying to use the numpy version that you have installed:
  your installation is broken - please reinstall numpy.
- If you have already reinstalled and that did not fix the problem, then:
  1. Check that you are using the Python you expect (you're using /usr/bin/python3),
     and that you have no directories in your PATH or PYTHONPATH that can
     interfere with the Python and numpy versions you're trying to use.
  2. If (1) looks fine, you can open a new issue at
     https://github.com/numpy/numpy/issues.  Please include details on:
     - how you installed Python
     - how you installed numpy
     - your operating system
     - whether or not you have multiple versions of Python installed
     - if you built from source, your compiler versions and ideally a build log


     Note: this error has many possible causes, so please don't comment on
     an existing issue about this - open a new one instead.

Original error was: /usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so: undefined symbol: PyExc_ImportError

*关于Numpy Github的问题看起来很相似,但实际解决方案从未发布:

https://github.com/numpy/numpy/issues/14480

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 12:22:51 2896 0
1 条回答
写回答
取消 提交回答
  • 我在这里偶然发现了解决方案。我仍然不清楚问题是什么以及为什么可以解决这个问题,但是增加了

    void\*onst libpython_handle = dlopen("libpython3.7m.so", RTLD_LAZY | RTLD_GLOBAL);
    

    Py_Initialize();之前 我的test_lib.cpp中的解决了该问题。

    回答来源:stackoverflow

    2020-03-24 12:22:59
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
From Python Scikit-Learn to Sc 立即下载
Data Pre-Processing in Python: 立即下载
双剑合璧-Python和大数据计算平台的结合 立即下载