首页 > 解决方案 > Pybind11 类型错误。Python 无法识别已知类型

问题描述

我完全没有想法。简而言之:

>>> franka_o80.function_using_mode(o80.Mode.QUEUE)
TypeError: dummy3(): incompatible function arguments. The following argument types are supported:
    1. (arg0: o80::Mode) -> None
Invoked with: Mode.QUEUE

详细说明:

  1. 有一个软件o80,有C++ enum Mode,编译成o80.so. 还有 pybind11 绑定,导出enum Modeo80.Modein o80_python.so
  2. 有一个o80_example带有通讯员o80_example.so和的玩具示例o80_example_python.so。我可以:
import o80
import o80_example
o80_example.function_accepting_mode(o80.Mode.QUEUE)
  1. 有我的项目,我在做同样的事情,但我得到了上面粘贴的内容。看起来 pybind在代码Modeo80_python.soo80::Mode代码中没有发现任何关系。我什至可以做pybind11::class_<o80::Mode>("OtherMode");,然后传入OtherMode我的function_using_mode-pybind 看不出问题。from 的函数o80通常都在工作,问题仅出在类型上。

也作为症状: 这是正常的:(arg0: o80.Mode) -> None 这就是我所拥有的:(arg0: o80::Mode) -> None

我尝试了什么:

  1. typedefunsing namespace
  2. 检查typeid().hash_codeand在andtypeid().name中是相同的- 它们是相同的o80franka_o80
  3. 将文件放在与原始文件相同的目录中 - 没有帮助
  4. 查看编译指令:
o80_example:
/usr/bin/c++ -fPIC  -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic  -shared -Wl,-soname,libo80_example.so -o libo80_example.so CMakeFiles/o80_example.dir/src/driver_in.cpp.o CMakeFiles/o80_example.dir/src/driver_out.cpp.o CMakeFiles/o80_example.dir/src/standalone.cpp.o CMakeFiles/o80_example.dir/src/driver.cpp.o  -Wl,-rpath,/home/franka_panda/o80/install/lib::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.71.0 /home/franka_panda/o80/install/lib/libo80.so /home/franka_panda/o80/install/lib/libsynchronizer.so /home/franka_panda/o80/install/lib/libtime_series.so /home/franka_panda/o80/install/lib/libshared_memory.so /usr/lib/x86_64-linux-gnu/librt.so /home/franka_panda/o80/install/lib/libreal_time_tools.so /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_atomic.so.1.71.0 -lpthread -lpthread -ledit -lcurses -lnsl -lglut -lGL -lGLU -lX11 -lXmu -lm /home/franka_panda/o80/install/lib/libsignal_handler.so 

/usr/bin/c++  -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -DRT_PREEMPT -DUSING_pybind11 -Do80_example_py_EXPORTS -I/home/franka_panda/o80/src/o80_example/include -I/home/franka_panda/o80/src/o80_example/SYSTEM -isystem /usr/include/python3.8 -isystem /home/franka_panda/o80/install/include -isystem /usr/include/eigen3  -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -fPIC   -fvisibility=hidden -std=gnu++17 -o CMakeFiles/o80_example_py.dir/srcpy/wrappers.cpp.o -c /home/franka_panda/o80/src/o80_example/srcpy/wrappers.cpp

/usr/bin/c++ -fPIC  -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic -Wl,--no-as-needed -Wall -Wextra -Wpedantic  -shared  -o o80_example.cpython-38-x86_64-linux-gnu.so CMakeFiles/o80_example_py.dir/srcpy/wrappers.cpp.o  -Wl,-rpath,/home/franka_panda/o80/build/o80_example:/home/franka_panda/o80/install/lib:::::::::::::::: /usr/lib/x86_64-linux-gnu/libpython3.8.so libo80_example.so /home/franka_panda/o80/install/lib/libo80.so /home/franka_panda/o80/install/lib/libsynchronizer.so /home/franka_panda/o80/install/lib/libtime_series.so /home/franka_panda/o80/install/lib/libshared_memory.so /usr/lib/x86_64-linux-gnu/librt.so /home/franka_panda/o80/install/lib/libreal_time_tools.so /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_atomic.so.1.71.0 -lpthread -lpthread -ledit -lcurses -lnsl -lglut -lGL -lGLU -lX11 -lXmu -lm /home/franka_panda/o80/install/lib/libsignal_handler.so

franka_o80:
/usr/bin/c++ -fPIC  -Wl,--no-as-needed /usr/local/lib/libreal_time_tools.so /usr/local/lib/libshared_memory.so /usr/local/lib/libsignal_handler.so /usr/local/lib/libsynchronizer.so /usr/local/lib/libtime_series.so /usr/local/lib/libo80.so -Wl,-rpath,/usr/local/lib -shared -Wl,-soname,libfranka_o80_cpp.so -o libfranka_o80_cpp.so CMakeFiles/franka_o80_cpp.dir/src/driver.cpp.o CMakeFiles/franka_o80_cpp.dir/src/driver_input_output.cpp.o CMakeFiles/franka_o80_cpp.dir/src/driver_input.cpp.o CMakeFiles/franka_o80_cpp.dir/src/driver_output.cpp.o CMakeFiles/franka_o80_cpp.dir/src/kinematics.cpp.o CMakeFiles/franka_o80_cpp.dir/src/standalone.cpp.o CMakeFiles/franka_o80_cpp.dir/src/states.cpp.o CMakeFiles/franka_o80_cpp.dir/src/state.cpp.o   -L/opt/ros/noetic/lib  -Wl,-rpath,/opt/ros/noetic/lib -lfranka -lpinocchio /usr/lib/x86_64-linux-gnu/libboost_system.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.71.0 -lrt -lpthread /usr/lib/x86_64-linux-gnu/libboost_atomic.so.1.71.0 -lpthread 

/usr/bin/c++  -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -DROSCONSOLE_BACKEND_LOG4CXX -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"franka_o80\" -DRT_PREEMPT -DUSING_pybind11 -Dfranka_o80_EXPORTS -I/opt/ros/noetic/include -I/opt/ros/noetic/include/libfranka -I/opt/ros/noetic/share/xmlrpcpp/cmake/../../../include/xmlrpcpp -I/usr/include/eigen3 -isystem /usr/include/python3.8  -fPIC   -fvisibility=hidden -Wl,--no-as-needed -std=gnu++17 -o CMakeFiles/franka_o80.dir/src/wrappers.cpp.o -c /home/franka_panda/franka_o80/src/wrappers.cpp

/usr/bin/c++ -fPIC  -Wl,--no-as-needed /usr/local/lib/libreal_time_tools.so /usr/local/lib/libshared_memory.so /usr/local/lib/libsignal_handler.so /usr/local/lib/libsynchronizer.so /usr/local/lib/libtime_series.so /usr/local/lib/libo80.so -Wl,-rpath,/usr/local/lib -shared -Wl,-soname,libfranka_o80_cpp.so -o libfranka_o80_cpp.so CMakeFiles/franka_o80_cpp.dir/src/driver.cpp.o CMakeFiles/franka_o80_cpp.dir/src/driver_input_output.cpp.o CMakeFiles/franka_o80_cpp.dir/src/driver_input.cpp.o CMakeFiles/franka_o80_cpp.dir/src/driver_output.cpp.o CMakeFiles/franka_o80_cpp.dir/src/kinematics.cpp.o CMakeFiles/franka_o80_cpp.dir/src/standalone.cpp.o CMakeFiles/franka_o80_cpp.dir/src/states.cpp.o CMakeFiles/franka_o80_cpp.dir/src/state.cpp.o   -L/opt/ros/noetic/lib  -Wl,-rpath,/opt/ros/noetic/lib -lfranka -lpinocchio /usr/lib/x86_64-linux-gnu/libboost_system.so.1.71.0 /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.71.0 -lrt -lpthread /usr/lib/x86_64-linux-gnu/libboost_atomic.so.1.71.0 -lpthread 

我看不到黑暗魔法发生在哪里。

我的CMakeLists.txt

# franka_o80_cpp
add_library(franka_o80_cpp SHARED ..........)
target_include_directories(franka_o80_cpp PUBLIC ${franka_control_INCLUDE_DIRS})
target_include_directories(franka_o80_cpp PUBLIC ${pinocchio_INCLUDE_DIRS})
target_include_directories(franka_o80_cpp PUBLIC ${EIGEN3_INCLUDE_DIRS})
target_link_directories(franka_o80_cpp PUBLIC ${franka_control_LIBRARY_DIRS})
target_link_libraries(franka_o80_cpp PUBLIC franka)
target_link_libraries(franka_o80_cpp PUBLIC pinocchio)
target_link_libraries(franka_o80_cpp PUBLIC Boost::system Boost::thread)
target_link_libraries(franka_o80_cpp PUBLIC rt pthread)
target_compile_options(franka_o80_cpp PUBLIC -Wl,--no-as-needed)
target_link_options(franka_o80_cpp PUBLIC -Wl,--no-as-needed /usr/local/lib/libreal_time_tools.so /usr/local/lib/libshared_memory.so /usr/local/lib/libsignal_handler.so /usr/local/lib/libsynchronizer.so /usr/local/lib/libtime_series.so /usr/local/lib/libo80.so -Wl,-rpath,/usr/local/lib)
# franka_o80
if (pybind11_FOUND)
    add_library(franka_o80 MODULE src/wrappers.cpp)
    target_compile_definitions(franka_o80 PRIVATE USING_pybind11)
    target_link_libraries(franka_o80 PRIVATE pybind11::module)
    target_link_libraries(franka_o80 PRIVATE ${PYTHON_LIBRARIES})
    target_link_libraries(franka_o80 PRIVATE franka_o80_cpp)
    set_target_properties(franka_o80 PROPERTIES PREFIX "")
endif()

代码,相当无聊:

pybind11::module::import("o80");
m.def("fucntion_using_mode", [](o80::Mode){});

所有其他类型都会发生同样的事情,Mode只是为了简单。Ubuntu 20.04,g++ 9.3.0。请帮忙。o80有过度设计的生态系统,需要数周时间才能与它整合。我会提供我能提供的所有日志。谢谢你。

UPD:将链接选项从 更改-lo80o80.so,仍然不起作用。

标签: pythonc++cmaketypeerrorpybind11

解决方案


为了让pybind11把两个类视为相同,不仅它们的名称应该相同,而且文件也应该相同。o80的绑定是用path_to_sources/install/include包含编译的,但我的绑定是用/usr/local/include包含编译的,所以 Python 无法识别它们。


推荐阅读