python - 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
详细说明:
- 有一个软件
o80
,有C++enum Mode
,编译成o80.so
. 还有 pybind11 绑定,导出enum Mode
到o80.Mode
ino80_python.so
。 - 有一个
o80_example
带有通讯员o80_example.so
和的玩具示例o80_example_python.so
。我可以:
import o80
import o80_example
o80_example.function_accepting_mode(o80.Mode.QUEUE)
- 有我的项目,我在做同样的事情,但我得到了上面粘贴的内容。看起来 pybind在代码
Mode
中o80_python.so
和o80::Mode
代码中没有发现任何关系。我什至可以做pybind11::class_<o80::Mode>("OtherMode");
,然后传入OtherMode
我的function_using_mode
-pybind 看不出问题。from 的函数o80
通常都在工作,问题仅出在类型上。
也作为症状: 这是正常的:(arg0: o80.Mode) -> None
这就是我所拥有的:(arg0: o80::Mode) -> None
我尝试了什么:
- 玩
typedef
和unsing namespace
- 检查
typeid().hash_code
and在andtypeid().name
中是相同的- 它们是相同的o80
franka_o80
- 将文件放在与原始文件相同的目录中 - 没有帮助
- 查看编译指令:
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:将链接选项从 更改-lo80
为o80.so
,仍然不起作用。
解决方案
为了让pybind11把两个类视为相同,不仅它们的名称应该相同,而且文件也应该相同。o80
的绑定是用path_to_sources/install/include
包含编译的,但我的绑定是用/usr/local/include
包含编译的,所以 Python 无法识别它们。
推荐阅读
- javascript - Highcharts 多系列结合linkedTo悬停问题
- swift - 如何将文档保存到图库?- 斯威夫特
- linux - 如何使用 NFS 挂载 rootfs 以在 qemu 上模拟 ARM 架构?
- c - Atoi() 和 strtol() 在 C 中无法正常工作
- awk - 如何使用 grep 对列表进行排序以显示基于预定义列表的唯一出现次数?
- reactjs - 使用 useRef 访问许多类
- c++ - 使用 MPI 在 C++ 中的 BubbleSort
- node.js - req.body.caption 返回 null
- python - 如何运行在 Django 中无限运行的外部 python 脚本并在 html 中打印所有输出?
- php - 会话在 Laravel 中的支付网关回调时自动销毁