介绍
pybind11 是一个轻量级的 header-only 库,可以将 C++ 类型暴露给 Python,反之亦然,主要用来将 C++ 接口转成 Python。
安装
apt install python3-dev
git clone https://github.com/pybind/pybind11/
git submodule update --init --recursive
如果需要交叉编译 arm64 平台,会需要 aarch64-linux-gnu 中的头文件,可以改名或者下载
构建
CMakeLists.txt:
add_subdirectory(pybind11)
target_link_libraries(${PROJECT_NAME} PUBLIC pybind11)
pybind11_add_module(${PROJECT_NAME} SHARED src/python.cpp) # 类似 add_library
C++ 使用
python.cpp
普通函数
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int x, int y) {
return x + y;
}
PYBIND11_MODULE(py_sample, m) {
m.doc() = "py_sample";
m.def("add", &add, "add func");
}
struct 和 class(enum 类似)
struct {
int a;
string b;
};
PYBIND11_MODULE(py_sample, m) {
py::class_<SomeClass>(m, "SomeClass")
.def(py::init<int, string>())
.def_readwrite("a", &SomeClass::a)
.def_readwrite("b", &SomeClass::b);
}
如果包含裸指针,可以使用 def_buffer,在 python 中直接用 np.array(matrix_instance, copy = False)
来使用,详见
编译
cmake .. -DPYTHON_EXECUTABLE=/xxxx/python3.7m
make -j8
编译时会运行 python 获得一些参数 ,详见https://github.com/pybind/pybind11/blob/master/tools/FindPythonLibsNew.cmake#L113
结果会编译出 py_sample.cpython-37m-x86_64-linux-gnu.so,后缀由变量 PYTHON_MODULE_EXTENSION 决定,需要保证编译和运行的机器 python minor 版本一致。
Python 调用
export PYTHONPATH=so_path
import py_sample
sum = py_sample.add(1, 5)
print(sum)
some = SomeClass(2, "sssss")
print(some.a, " ", some.b)