我一直试图让我的项目运行,但我遇到了麻烦。经过多次调试后,我已经缩小了问题但不知道如何继续。
有些背景,我在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: undefined symbol: _Py_ZeroStruct
我在我的可执行文件和共享库上运行了ldd,没有一点区别。我还在上面的文件上运行了nm -D,_Py_ZeroStruct确实是未定义的。如果你们想要打印命令,我很乐意提供它们。非常感谢任何建议,谢谢。
这是完整的python错误:
Traceback (most recent call last): File "/usr/lib/python2.6/dist-packages/numpy/__init__.py", line 130, in import add_newdocs File "/usr/lib/python2.6/dist-packages/numpy/add_newdocs.py", line 9, in from lib import add_newdoc File "/usr/lib/python2.6/dist-packages/numpy/lib/__init__.py", line 4, in from type_check import * File "/usr/lib/python2.6/dist-packages/numpy/lib/type_check.py", line 8, in import numpy.core.numeric as _nx File "/usr/lib/python2.6/dist-packages/numpy/core/__init__.py", line 5, in import multiarray ImportError: /usr/lib/python2.6/dist-packages/numpy/core/multiarray.so: undefined symbol: _Py_ZeroStruct Traceback (most recent call last): File "/home/constantin/workspace/OpenRAVE/src/grasp_behavior_2.py", line 3, in from openravepy import * File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py", line 35, in openravepy_currentversion = loadlatest() File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py", line 16, in loadlatest return _loadversion('_openravepy_') File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py", line 19, in _loadversion mainpackage = __import__("openravepy", globals(), locals(), [targetname]) File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/_openravepy_/__init__.py", line 29, in from openravepy_int import * ImportError: numpy.core.multiarray failed to import
答案 0 :(得分:9)
我的应用程序遇到了同样的问题并解决了它没有将 python链接到可执行文件。
设置如下:
可执行文件 - 链接 - >库 - 动态加载 - >插件 - 加载 - > python口译员
避免ImportErrors的解决方案是更改dlopen的参数,插件加载到RTLD_GLOBAL
。
dlopen("plugin.so", RTLD_NOW | RTLD_GLOBAL)
这使符号可用于之后加载的其他内容,即其他插件或python解释器。
然而,可能会发生符号冲突,因为插件稍后会导出相同的符号。
答案 1 :(得分:2)
解决方案是将python2.6库与我的可执行文件链接起来。
即使可执行文件没有进行python调用,它也需要与python库链接。我假设它是因为我的共享库没有将python库的符号传递给可执行文件。如果有人能解释为什么我的可执行文件(在运行时加载我的动态库,没有链接)需要这些符号,那就太棒了。
为了澄清,我的程序模型类似于: [我的可执行文件] - (动态加载) - > [我的共享图书馆] - (与之通话和链接) - > [Python共享库]
答案 2 :(得分:0)
检查你的python-headers和python的运行时。看起来你有2.5和2.6版本的混合。
答案 3 :(得分: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()