Cython

Cython

编译运行

  • Use setup.py file
from setuptools import setup
from Cython.Build import cythonize
from Cython.Compiler import Options

Options.docstring = False

setup(
    name='Hello world app',
    ext_modules=cythonize("hello.pyx", compiler_directives={'embedsignature': True}), # target .pyx file and compile options
    zip_safe=False,
)

如果是要传入多个文件,可以使用正则表达式匹配,eg. *.pyx 。或者使用一个字符串的列表包含。

编译:

python setup.py build_ext --inplace
  • Use pyximport

  • Use Jupyter Notebook

%load_ext Cython

# Start a new cell
%%cython

cdef int a = 0
for i in range(10):
    a += i
print(a)

编译选项

编译选项如上 setup.py 中所示,使用 Options 设置,参考

compiler derctives 可以在 setup.py 中设置,或者是在 .pyx 文件顶部加入如下注释

#cython: language_level=3, ...

变量类型

声明变量类型,可以声明几乎所有的 C 类型(数,指针,结构体,联合体)

cdef int i # declare an integer

函数类型声明

cdef int func(int a, int b)

cpdef int func(int a, int b)

cdef 只能在 .pyx 内调用,无法向 Python 提供接口。cpdef 可以向 Python 提供接口。

  • C array
cdef int p[1000]

for i in p[:100]:
    if i % 10 == 0:
        a += i

从官方给出样例中可以看出,数组是可以用 Python 切片并且循环的。与 C 相同,函数中声明的变量放在堆栈(stack)中,所以不要声明过大的数组。关于堆栈和堆,参考

  • string

返回字符串

from libc.stdlib cimport malloc
from libc.string cimport strcpy, strlen

cdef char* hello_world = 'hello world'
cdef Py_ssize_t n = strlen(hello_world)


cdef char* c_call_returning_a_c_string():
    cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
    if not c_string:
        raise MemoryError()
    strcpy(c_string, hello_world)
    return c_string

不要在函数里面声明一个字符数组然后返回。因为这个字符数组是在函数栈里面,函数返回后就释放了。应该使用 malloc 动态分配空间后返回!!!

函数调用

通过头文件和链接库就可以随意调用 C 函数

# Python 可以直接调用
cdef extern from "add.h":
    cpdef int func(int, int)
  
# Python 不可直接调用
cdef extern from "add.h":
    int func(int, int)

setup.py

from setuptools import setup, Extension
from Cython.Build import cythonize

ext_modules = [
    Extension("space",
              sources=["space.pyx"],
              include_dis = ['./']
              libraries=["add"],  # Unix-like specific
              library_dirs = ['./']
              ),
]

setup(
    name='Hello world app',
    ext_modules=cythonize(ext_modules), 
    zip_safe=False,
)

将之前的 C 函数编译成动态链接库。然后在 .pyx 中导入头文件并声明函数。之后再 setup.py 中编译链接,就可以调用 C 函数。编译时Extension参数见此处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值