12

我一直试图让我的一个项目运行,但我遇到了麻烦。经过多次调试,我缩小了问题范围,但不知道如何进行。

一些背景,我在 C++ 代码中使用 python 脚本。这在 Python 上有一些记录,我设法让它在我的基本可执行文件中运行得很好。#include 和 -lpython2.6 一切都很棒。

但是,从共享库 (.so) 运行此 python 脚本时出现了困难。这个共享库被模拟系统(OpenRAVE)“加载”为“模块”。系统使用名为 SendCommand 的“模块”虚拟方法与该模块交互。然后该模块启动一个 boost::thread,给 python 自己的线程,并返回到模拟系统。但是,当 python 开始导入其模块并因此加载其动态库时它会失败,我认为是由于以下错误:

ImportError:/usr/lib/python2.6/dist-packages/numpy/core/multiarray.so:未定义符号:_Py_ZeroStruct

我已经在我的可执行文件和共享库上运行了 ldd,没有什么区别。我还在上面的文件上运行了 nm -D,_Py_ZeroStruct 确实是未定义的。如果你们想打印命令,我很乐意提供它们。任何建议将不胜感激,谢谢。

这是完整的python错误:

回溯(最近一次通话最后):
  文件“/usr/lib/python2.6/dist-packages/numpy/__init__.py”,第 130 行,在
    导入 add_newdocs
  文件“/usr/lib/python2.6/dist-packages/numpy/add_newdocs.py”,第 9 行,在
    从库导入 add_newdoc
  文件“/usr/lib/python2.6/dist-packages/numpy/lib/__init__.py”,第 4 行,在
    从 type_check 导入 *
  文件“/usr/lib/python2.6/dist-packages/numpy/lib/type_check.py”,第 8 行,在
    将 numpy.core.numeric 导入为 _nx
  文件“/usr/lib/python2.6/dist-packages/numpy/core/__init__.py”,第 5 行,在
    导入多数组
ImportError:/usr/lib/python2.6/dist-packages/numpy/core/multiarray.so:未定义符号:_Py_ZeroStruct
回溯(最近一次通话最后):
  文件“/home/constantin/workspace/OpenRAVE/src/grasp_behavior_2.py”,第 3 行,在
    从 openravepy 导入 *
  文件“/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py”,第 35 行,在
    openravepy_currentversion = loadlatest()
  文件“/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py”,第 16 行,在 loadlatest
    返回 _loadversion('_openravepy_')
  _loadversion 中的文件“/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py”,第 19 行
    mainpackage = __import__("openravepy", globals(), locals(), [targetname])
  文件“/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/_openravepy_/__init__.py”,第 29 行,在
    从 openravepy_int 导入 *
ImportError:numpy.core.multiarray 导入失败
4

4 回答 4

9

我的应用程序遇到了同样的问题,并在没有将python 链接到可执行文件的情况下解决了它。

设置如下:

可执行文件 --链接--> 库 --动态加载--> 插件 --加载--> python 解释器

避免 ImportErrors 的解决方案是更改 dlopen 的参数,插件加载到RTLD_GLOBAL.

dlopen("plugin.so", RTLD_NOW | RTLD_GLOBAL)

这使得符号可用于之后加载的其他东西,即其他插件或 python 解释器。

但是,可能会发生符号冲突,因为插件稍后会导出相同的符号。

于 2012-10-11T17:38:15.127 回答
2

解决方案是将 python2.6 库也与我的可执行文件链接起来。

即使可执行文件没有进行 python 调用,它也需要与 python 库链接。我假设它是因为我的共享库没有将 python 库的符号传递给可执行文件。如果有人能解释为什么我的可执行文件(在运行时加载我的动态库,没有链接)需要这些符号,那就太好了。

为了澄清起见,我的程序模型类似于:[我的可执行文件] -(动态加载)-> [我的共享库] -(调用和链接)-> [Python 共享库]

于 2011-11-29T15:56:56.120 回答
0

检查你的 python-headers 和 python 的运行时。看起来您混合了 2.5 和 2.6 版本。

于 2011-11-28T23:09:23.097 回答
0

在 openrave 中有一个示例,它展示了如何在不让应用程序知道的情况下构建使用 boost python 的 C++ 共享对象:

http://openrave.org/en/coreapihtml/orpythonbinding_8cpp-example.html

在此处的 cmake 文件中搜索“python”:

https://openrave.svn.sourceforge.net/svnroot/openrave/trunk/src/cppexamples/CMakeLists.txt

相关信息是:

if( Boost_PYTHON_FOUND AND Boost_THREAD_FOUND )
  find_package(PythonLibs)
  if( PYTHONLIBS_FOUND OR PYTHON_LIBRARIES )
    if( PYTHON_EXECUTABLE )
      # get the site-packages directory
      execute_process(
        COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)"
        OUTPUT_VARIABLE _python_sitepackage
        RESULT_VARIABLE _python_failed)
      if( ${_python_failed} EQUAL 0 )
        string(REGEX REPLACE "[\r\n]" "" _python_sitepackage "${_python_sitepackage}")
        set(PYTHON_INCLUDE_PATH ${PYTHON_INCLUDE_PATH} ${_python_sitepackage}/numpy/core/include)
      else()
        message(STATUS "failed to get python site-package directory")
      endif()
    endif()

    include_directories(${PYTHON_INCLUDE_PATH} ${OpenRAVE_INCLUDE_DIRS})
    add_library(orpythonbinding SHARED orpythonbinding.cpp)
    target_link_libraries(orpythonbinding ${OpenRAVE_LIBRARIES} ${PYTHON_LIBRARIES} ${Boost_PYTHON_LIBRARY} ${Boost_THREAD_LIBRARY})
    set_target_properties(orpythonbinding PROPERTIES PREFIX "" COMPILE_FLAGS "${OpenRAVE_CXX_FLAGS}")
    if( WIN32 )
      set_target_properties(orpythonbinding PROPERTIES SUFFIX ".pyd")
    endif()
  endif()
endif()
于 2011-12-03T04:44:43.677 回答