学习 pybind11 (2):Hello World 示例
首先要明白pybind11是干啥的,对于一个C/C++库,可以用pybind11封装它的接口为Python接口,这样得到一个python库,就可以把功能强大的库丢给使用python的boys & girls使用了~
因此,使用pybind11做封装,是我们“library developer”干的事情,说不上底层,但也比较底层了。你应该会用CMake,你也应该熟悉C/C++和Python。你编译出来的python库,其实就是一个.so结尾的动态库,也就是python里的一个module。
现在实现一个add(a, b)
的接口,功能是计算两个数字的和。不考虑各种边界情况。
开工:
mkdir -p ~/work/test/toy
cd $_
mkdir 3rdparty
git clone https://github.com/pybind/pybind11 3rdparty/pybind11
mkdir build
mkdir src
touch src/example.cpp
touch CMakeLists.txt
目录结构:
src/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 which adds two numbers");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(toy)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(3rdparty/pybind11)
pybind11_add_module(example src/example.cpp)
执行构建:
cd build
cmake ..
make
其中红框里的.so文件就是我们生成的python库了。在python中加载它(盘它!):
python
import example
example.add(100, 200)
example.__doc__
简要分析说明
这里的CMakeLists.txt中,通过加载pybind11目录,会把pybind11/tools/pybind11Tools.cmake
中的pybind11_add_module()
函数引入。这个函数的功能,是创建一个指定名字的库(target是一个动态库);但是,会修改库文件名字的前缀后缀;并且还有一堆其他的编译链接设定。因此这里不通过手动add_library()
命令来创建target,而是先包含pybind11目录再用pybind11_add_module()
函数。
也就是说,pybind11被当成一个3rdparty库被引入当前工程。从代码版本控制的角度看,可以把它弄成一个submodule,当然如果强项作为源码管理也可以,但是要注意tests子目录有3M大,可以考虑删除。
C/C++代码中的example
和CMakeLists.txt
中的target名字,要保持一致吗?
是的,要保持一致。譬如把C++中的example
改为exampleMod
则虽然能编译出库,但是Python中无法import:
上一篇: pybind11-python C/C++ 扩展编译
下一篇: pybind11-类, 结构
推荐阅读
-
从零基础到精通:实战对比 Activiti工作流的入门与实战Hello World示例 (通过API和案例教学)
-
fxgl - 2 - hello world
-
JNI编程实战入门:从Hello World实例开始学习
-
pybind11 的 Hello World
-
学习 pybind11 (2):Hello World 示例
-
深度学习实践学习(PyTorch 版)代码说明 - 52 [World2Vec_Learning
-
C 语言学习 2:Windows 通过命令行编译和运行 c 程序(Hello World)及程序详情
-
跟随《自然》学习制图:R 语言 ggplot2 叠加条形图完整示例
-
跟随《自然》学习制图:R 语言 ggplot2 环形堆叠条形图完整示例
-
还原法学习--示例 1:数组求和 const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((accumulator, currentValue) => { return accumulator + currentValue; }, 0); const sum = numbers. }, 0); console.log(sum); // // currentValue; } }. console.log(sum); // 输出:10 在本例中,我们没有提供 initialValue,因此累加器的初始值是数组的第一个元素 1,而 currentValue 则从数组的第二个元素 2 开始。 例 2:扁平化二维数组