一、引言
C++功能强大,具有广泛的是用户基础,所以很多产品的API都是基于C++提供的。Python的简洁和高效也是无需多言,是很多工程师和项目的首选。那么如果遇到了仅提供C++ API的产品,但想通过Python进行二次项目研发的情况该如何处理呢?
通过Python调用C++函数的方法有很多,像Boost, Pybind11等都可实现,经过综合测试和评估,最后选择了Pybind11。
二、安装pybind11
Ubuntu 20.04上安装方法:
$ sudo apt install pybind11-dev python3-pybind11
三、创建一个Demo
首先创建一个C++小程序sum2num.cpp,计算两个数之和:
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(sum2num, m) {
m.doc() = "pybind11 example";
m.def("add", &add, "A function which adds two numbers");
}
主要关注是前两行的引入头文件及声明,以及最后一段的模块定义,模块名称是sum2num。
然后创建Makefile文件:
default:
g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` `python3-config --ldflags` -o sum2num`python3-config --extension-suffix` sum2num.cpp
clean:
@rm -f *.so
保存后执行"make"就能编译出sum2num.cpython-38-x86_64-linux-gnu.so模块了。
上面Makefile里面有三个变量,可以分别通过echo打印出来:
$ echo `python3 -m pybind11 --includes`
-I/usr/include/python3.8 -I/home/zwang/.local/include/python3.8 (即头文件路径)
$ echo `python3-config --ldflags`
-L/usr/lib/python3.8/config-3.8-x86_64-linux-gnu -L/usr/lib -lcrypt -lpthread -ldl -lutil -lm -lm, (即链接库路径)
$ echo `python3-config --extension-suffix`
.cpython-38-x86_64-linux-gnu.so(即目标库文件的后缀)
然后就可以创建一个Python脚本test.py测试了:
#!/usr/bin/python
import sys
sys.path.append('.')
import sum2num
print("python import c++ module demo: sum2num.add(3, 4) result")
print(sum2num.add(3, 4))
测试结果:
$ ./test.py
python import c++ module demo: sum2num.add(3, 4) result
7
然后回到文章开始的应用场景问题,对于只提供了C++ API的凯视佳UC3D激光线轮廓相机,可以将其采集数据部分编译成Python模块,通过调用该模块获取到采集的点云数据,然后就可以调用任意Python PCL库进行处理和解析了。
有关Python PCL库的选型详情可参见:Ubuntu 20.04编译安装open3d点云处理库