pybind11 是一个轻量级的头文件库,用于连接C++和python联合编程,主要用于Python绑定的现有C++代码。
# 安装
python3 -m pip install pybind11
# Linux/macOS依赖
- python3-dev 和 cmake
python3 -m pip install python3-dev
brew uninstall cmake
# 调用pybind11需要的头文件和命名空间:
#include <pybind11/pybind11.h>
namespace py = pybind11;
# 简单例子:
## 构建函数add():
int add(int i, int j) {
return i + j;
}
为了简单起见,将把函数和绑定代码放在一个名为example.cpp中, cpp包含以下内容:
注:实际中,实现和绑定代码通常位于不同的文件中
- example.cpp
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function that adds two numbers");
}
- pybind11封装c++ 代码使用PYBIND11_MODULE 方法即可;
- PYBIND11_MODULE()宏创建一个函数,可以从Python内使用import调用该函数;
- 模块名是第一个参数, 第二个参数(m)定义了py::module_u类型的变量,它是创建绑定的主接口;
- 方法模块
module_::def()
生成绑定代码,将add()函数提供给给Python。
## 编译:
#mac
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
或
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
#linux
g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
## 调用
>>> import example
>>> example.add(1, 2)
## 参数关键字
// regular notation
m.def("add", &add, "A function which adds two numbers",
py::arg("i"), py::arg("j"));
或
// shorthand
using namespace pybind11::literals;
m.def("add2", &add,"A function which adds two numbers", "i"_a, "j"_a);
## 调用
>>> import example
>>> example.add(i=1, j=2)
# 3
help(example)
FUNCTIONS
add(...) method of builtins.PyCapsule instance
add(i: int, j: int) -> int
A function which adds two numbers
## 默认参数
- 使用arg扩展
// shorthand
m.def("add", &add, "A function which adds two numbers",
py::arg("i") = 1, py::arg("j") = 2);
或
// shorthand
m.def("add", &add, "A function which adds two numbers","i"_a=1, "j"_a=2);
- 下面这种方式不可行; pybind11无法自动提取这些参数:
int add(int i = 1, int j = 2) {
return i + j;
}
## 调用
>>> import example
>>> example.add(i=1, j=2)
3
## 导出变量
从C++导出变量,使用 attr
函数就可以;内置类型和常规对象在指定为属性(attr
)时会自动转换,并且可以使用函数py::cast显式转换。
PYBIND11_MODULE(example, m) {
m.attr("the_answer") = 42;
py::object world = py::cast("World");
m.attr("what") = world;
}
>>> import example
>>> example.the_answer
42
>>> example.what
'World'
更多的数据类型转换见Type conversions
# 参考:
网友评论