首先,安装:

  • 通过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'