我正在重新评估将外部 C 库包装到 Python 中的不同方法。我很久以前就选择使用简单的 Python C API,它快速、简单、独立,而且,正如我所想的那样,它是面向未来的。然后我偶然发现了PyPy
,它显然不打算支持 CPython API,但将来可能会成为一个有趣的替代方案......因此我正在寻找更高级别的入口点。ctypes
速度很慢,所以现在我又回到了cython
,这似乎在努力支持 PyPy。
我的库有许多具有相同签名的函数,因此我广泛使用 C 预处理器宏来生成 Python 模块。我认为这在 cython 中会变得更舒服,因为我可以访问整个 Python 语言。但是,我在为我的函数包装器编写工厂时遇到了麻烦:
import cython
from numpy cimport ndarray, double_t
cimport my_c_library
cdef my_c_library.data D
ctypedef double_t DTYPE_t
cdef parse_args(ndarray[DTYPE_t] P, ndarray[DTYPE_t] x, ndarray[DTYPE_t] y):
D.n = P.size
D.m = x.size
D.P = <double*> P.data
D.x = <double*> x.data
D.y = <double*> y.data
def _fun_factory(name):
cpdef fun(ndarray[DTYPE_t] P, ndarray[DTYPE_t] x, ndarray[DTYPE_t] y):
parse_args(P, x, y)
getattr(my_c_library, name)(&D)
return y
return fun
fun1 = _fun_factory('fun1')
fun2 = _fun_factory('fun2')
# ... many more function definitions ...
cython 编译器抱怨:“这里不允许 C 函数定义”,指的是cpdef
内部_fun_factory
。这里有什么问题?我认为pyx
文件就像普通的 python 文件一样。除了从单独的 python 脚本动态生成文件之外,有没有办法让它工作pyx
,例如setup.py
?
我也很惊讶 cython 不允许我这样做:
ctypedef ndarray[double_t, ndim=1] p_t
清理代码。为什么这不起作用?
我知道那里有自动C -> cython
翻译器,但我不愿意让自己依赖这样的第 3 方工具。但是,如果您认为它已准备好用于生产,请随时提出建议。