一、前言
pybind11是一个只包含头文件的轻量级库,可以通过它实现C/C++接口的调用,相比于boost.python, swig, ctypes等,pybind11的优点是API比较简单且对C++ 11支持很好。下面介绍pybind11的基本入门操作。
二、使用示例
(1)源码下载
git clone https://github.com/pybind/pybind11.git
(2)创建C++函数与python的绑定关系
创建example.cpp文件,代码如下:
#include
namespace py = pybind11;
int add(int a, int b) {
return a + b;
}
PYBIND11_MODULE(example, m) {
m.def("add", &add, "A function which adds two numbers");
}
在其它模块调用import的时候,会调用宏PYBIND11_MODULE()创建的函数,它的第一个参数是模块名,第二个参数定义的是类型为py::module的变量,是用于创建bindings的接口,module::def()方法会生成binding的代码,将add()函数暴露给Python。
(3)编译
pybind11是一个仅有头文件的库,所以不需要链接其它的库,在Linux环境下,可以用以下的命令进行编译:
g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example.so
其中 python3 -m pybind11 --includes 会将编译所需要的头文件路径包括进来,比如我的环境中会输出:
-I/software/conda_envs/py35/include/python3.5m -I/software/pybind11/include
编译完成后会生成二进制的模块文件,通过import语句,可以装载并执行其中的函数:
>>> import example as e
>>> print(e.add(1, 2))
3
(4)设置参数默认值
C++可以为函数的参数设置默认值,但是pybind11目前并不会自动提取这些默认值,可以通过pybind11::arg()来指定:
m.def("add", &add, "A function which adds two numbers",
py::arg("a") = 1, py::arg("b") = 2);
或者
m.def("add", &add, "a"_a=1, "b"_a=2);
(5)导出变量
通过attr 函数可以导出C++中的变量,内置的C++类型和类对象如string在使用attr赋值时,会自动地进行类型转换,也可以通过pybind11::cast进行显示类型转换:
PYBIND11_MODULE(example, m) {
m.attr("age") = 42;
py::object name = py::cast("Oreo");
m.attr("name") = name;
}
这样这些变量就可以直接在python中访问
>>> import example as e
>>> print(e.age)
42
>>> print(e.name)
'Oreo'