pybind11库使用
首先,安装:
- 通过git的方式下载安装
- 通过包管理的方式下载安装:pip、conda-forge、vcpkg、brew
pybind11 是一个 header-only
的库,换句话说,只需要 C++ 项目里直接 include pybind11 的头文件就能使用。
获取pybind11
可以 git submodule
添加子模块,最好固定为某个版本:
git submodule add https://github.com/pybind/pybind11.git third_party/pybind11-2.5.0
cd third_party/pybind11-2.5.0/
git checkout tags/v2.5.0
或者,直接获取源码,放进相应子目录即可。
添加进cmake
CMakeLists.txt
里 add_subdirectory
pybind11 的路径,再用其提供的 pybind11_add_module
就能创建 pybind11 的模块了。
cmake_minimum_required(VERSION 3.1)
project(start-pybind11 VERSION 0.1.0 LANGUAGES C CXX)
set(MY_PYBIND ${CMAKE_CURRENT_SOURCE_DIR}/third_party/pybind11-2.5.0)
add_subdirectory(${MY_PYBIND})
pybind11_add_module(example_pb example_pb.cpp)
如果想在已有 C++ 动态库上扩展 pybind11 绑定,那么 target_link_libraries
链接该动态库就可以了。
target_link_libraries(example_pb PUBLIC example)
代码示例
在项目根目录创建一个example_pb.cc的文件
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example_pb, m) {
m.doc() = "example_pb bindings";
m.def("add", &add, "A function which adds two numbers");
}
example_pb:模型名,切记不需要引号
m:可以理解成模块对象
m.doc():help说明
m.def:用来注册函数和python打通界限
然后,进入cmake构建目录:
cd build
cmake ..
cmake --build .
编译完后,在 build 目录会生成一个 example_pb.cpython-310-x86_64-linux-gnu.so
的文件,文件名与编译环境有关,接着,就可以在该文件所在目录里通过python代码import调用。
$ python
Python 2.7.10 (default, Aug 22 2015, 20:33:39)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.add(1, 2)
3L
>>>
通过关键字传递参数
cpp文件中:
m.def("add", &add, "A function which adds two numbers",
py::arg("i"), py::arg("j"));
python使用:
>>> import example
>>> example.add(i=1, j=2)
3L
等价写法:
// regular notation
m.def("add1", &add, py::arg("i"), py::arg("j"));
// shorthand,C++11
using namespace pybind11::literals;
m.def("add2", &add, "i"_a, "j"_a);
默认参数值
m.def("add", &add, "A function which adds two numbers",
py::arg("i") = 1, py::arg("j") = 2);
等价写法:
// regular notation
m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);
// shorthand
m.def("add2", &add, "i"_a=1, "j"_a=2);
export变量
PYBIND11_MODULE(example, m) {
m.attr("the_answer") = 42;
py::object world = py::cast("World");
m.attr("what") = world;
}
cpp内置类型和通用对象可以自动转换,其它类型需要通过py::cast显示转化 通过export变量,可以通过模块访问cpp里定义的变量:
>>> import example
>>> example.the_answer
42
>>> example.what
'World'