pybind11
做了一些调研后,发现使用pybind11几乎是现在最方便的Python调用C++方法,本文对基本的操作方法做了一些记录。本文主要参考:pybind11官方文档
pybind11几乎是傻瓜式的操作。举个简单例子,现在需要实现一个Python接口调用自己已经写好的C++库,来打印输出图像的大小。
先看我们自己的C++库文件imagesize.h
和imagesize.cpp
:
1 2 3 4 5 6
| #include <iostream> #include <string> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp>
void showImageSize();
|
1 2 3 4 5 6 7
| #include "imagesize.h"
void showImageSize() { std::string imgPath = "/home/test.png"; cv::Mat img = cv::imread(imgPath); std::cout << "Image size: " << img.size << std::endl; }
|
然后是pybind11用于封装库的源文件pyimagesize.cpp
:
1 2 3 4 5 6 7 8 9 10 11
| #include <pybind11/pybind11.h> #include "imagesize.h"
namespace py = pybind11;
PYBIND11_MODULE(pyimagesize, m) { m.doc() = "Python binding of imagesize library";
m.def("showImageSize", &showImageSize); }
|
最后是整个项目的结构CMakeLists.txt
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| cmake_minimum_required(VERSION 3.5) project(testPybind)
set(CMAKE_CXX_FLAGS "-std=c++11") set(CMAKE_BUILD_TYPE "Debug")
find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS})
find_package(pybind11 REQUIRED)
add_library(imagesize SHARED imagesize.cpp) target_link_libraries(imagesize ${OpenCV_LIBS})
pybind11_add_module(pyimagesize pyimagesize.cpp) target_link_libraries(pyimagesize PRIVATE imagesize)
|
为简便起见,这些就是所有的代码了。编译后,会生成我们原先的共享库文件libimagesize.so和python封装为模块的共享库文件pyimagesize.cpython-35m-x86_64-linux-gnu.so。注意上面的模块名、文件名需要一一对应。接下来就可以在Python中调用自己写好的库函数了:
1 2 3 4 5 6 7 8
| $ python3 Python 3.5.2 (default, Apr 16 2020, 17:47:17) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pyimagesize >>> help(pyimagesize) >>> pyimagesize.showImageSize() Image size: 1080 x 1920
|
到此为止,已经全部完成。虽然例子很简单,但在此基础上扩展为更复杂的代码应该也不难。
pybind11对C++基本的语法、类、STL等都有很好的封装,此外对Eigen等类型也有原生很好的支持,具体可以参考官方文档。如果既想使用Python便捷的语法,又想要C++很高的运行效率,那么pybind11值得一试。特别是现在深度学习和SLAM结合日益紧密,pybind11以后应该是一个必备的技能。
个人理解错误的地方还请不吝赐教,转载请标明出处