使用 c++ 扩展python, pybind11

简介

python 是解释型语言, 语法写起来方便但执行速度较慢.
c++ 等编译语言速度最快, 但指针, 数组越界等 使用易犯错.
于是兼顾人的开发效率与执行效率, 有了这样的思想:

关键模块用C/C++ 写, 调用的时候使用 python 来调用, 即 extending python with c/c++.

这一设想被广泛地应用于各个解释型/ 托管 语言中. 如 java 可以有 native 方法来调用.

这里写图片描述

原理

python 目录的 include/ 目录下有相关头文件, 按照约定写一个wrapper, 就能与 python 解释器互通了.
包装下来代码量有点多, 因为不少代码是有规律的, 这意味着可以靠三方工具辅助, 如 pybind11.
还有个方案是 ctypes, python 自带的模块, 与 .so , .dll 交互. 见参考[5]

pybind11

几大优点:

  1. 可以优雅绑定 c++代码, 其他工具的教程以 C语言为主.
  2. 可以绑定 c++ 的类, 方便我们面向对象编程.
  3. 除了基本类型, stl的vector, map 也可以自动地与 python 的list, dict 等作参数自动转换.

从 PyBind11 生成的 Python 绑定(.pyd,.so)是一个完整的 Python 模块,可以直接导入和使用。意味着运行环境不需要安装 pybind11 的库依赖.
pip install pybind11 即可安装.

开发

  1. 业务逻辑.
  2. bind_module

类型选择

string 是万能的, 当 json 用, 可以嵌套很深.
numpy 对象. 见参考 [8,9].

编译

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
注意内含两个 动态变量. 先执行括号内 shell 语句, 再将结果作替换, 再执行整个 c++ 编译语句.

  • $(python3 -m pybind11 --includes)
  • $(python3-config --extension-suffix)
(base) yichu@ubuntu:~$ echo $(python3 -m pybind11 --includes)
-I/home/yichu/anaconda3/include/python3.9 -I/home/yichu/anaconda3/lib/python3.9/site-packages/pybind11/include
(base) yichu@ubuntu:~$ echo $(python3-config --extension-suffix)
.cpython-39-x86_64-linux-gnu.so

gcc(c++) -I 选项 可以指定本次编译的头文件目录. 详见参考[6].
gcc(c++) -fPIC 选项表示按照 位置无关( Position-Independent Code) 方式编译, 多用于 .so 共享库编译.

tips

  • 同一OS, 不同python版本下编译的 .so, 似乎并不通用. 报错为 找不到模块.

  • 加载时报错 undefined symbol.
    怀疑是 gcc 版本与系统库的版本差异.
    在这里插入图片描述

numpy 支持

todo.

参考

  1. python.org, Extending Python with C or C++
  2. python.org, writing-extensions-in-c++
  3. Wrapping C/C++ for Python
  4. Java native 本地方法调用
  5. ctypes wrapping
  6. blog,gcc 编译时 include 搜索路径
  7. 知乎, pybind11 最佳实践
  8. s.o.f. returning numpy arrays via pybind11
  9. pybind11—python numpy与C++数据传递
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值