Cython混编

  • 背景介绍
    Cython是一种针对Python语言与Cython扩展语言进行优化的静态编译器通过编写Cython接口代码,可以让Python代码与C/C++代码无缝衔接,达到为Python加速的目的。当然,也可以完全通过Cython接口重构Python代码,直接提速Python。整个过程可以表示为:首先将Cython接口代码转化为C/C++代码,然后将C/C++代码编译为动态链接库.pyd(Windows下)或.so文件(Linux下),即:
    Cython接口代码 $\rightarrow$ C/C++代码 $\rightarrow$ .pyd/.so动态库
    如果接口编写得当,通过Python调用该动态库文件较原生Python代码可提速两个量级。
    在语法层面,Cython几乎支持所有的Python语法,并且额外加入了一些C/C++的等效写法(提速的关键)。因此,在编写接口代码的时候势必两种写法都会用到,从而造成混乱。本文将主要介绍笔者习惯的Cython接口写法规范,可能会比较抽象。关于语法细节,建议参考官方文档:https://cython.org/

  >>>使用规范<<<

  • Python接口端实现Cython与Python之间的交互支持缺省参数
    • def $\rightarrow$ 函数接口
    • cdef class $\rightarrow$ 类接口
      此种情况下,类对象中self只能索引已存在的对象,不能直接创建新内容,功能上与this指针基本对标,此即self限制
    注意,不建议采用纯粹的class作为接口(因为健康的Python语法解除了对self的限制,从而无法与this指针对标,进而找不到C++对象并无法与C++对象直接映射),此种用法可以作为纯Python加速方案考虑。
  • C++接口端实现Cython与C++之间的交互不支持缺省参数
    • cdef $\rightarrow$ 函数接口
    • cdef struct $\rightarrow$ 类接口,不支持函数重载
    • cdef cppclass $\rightarrow$ 类接口,支持函数重载
    注意,Cython内部自身支持引用"&"与指针"*"操作,没有常量"const"限定(因此const一般忽略)。
  • 常见操作
    • 头部distutils标签
      # distutils: language = c++
    • 加载cython模块
      from libcpp.vector cimport vector
      from libcpp.string cimport string
      注意,vector映射Python中的Iterable对象,string映射Python中bytes对象。
    • 加载外部C++头文件及源文件
      cdef extern from '*.h':
          ...
      cdef extern from '*.cpp':
          pass
      注意,加载头文件是为了获取声明信息,加载源文件是为了获取定义信息。必须保证声明信息具有相应的定义内容(即实体)
  • 细节问题
    • setup.py文件中,sources参数必须保证加载到所有涉及到的C++源文件,但是不能重复加载
    • 当需要实例化一个C++接口下的类时,必须确保该类至少持有默认构造函数
    • 接口使用bool类型不安全

猜你喜欢

转载自www.cnblogs.com/xxhbdk/p/10173234.html
今日推荐