使用 Cython 从标头导出常量
Posted
技术标签:
【中文标题】使用 Cython 从标头导出常量【英文标题】:Export constants from header with Cython 【发布时间】:2015-08-01 21:06:22 【问题描述】:我正在使用 Cython 来包装 C 库。 C 库的头文件定义了许多常量,所以在我的 cython 模块中,我有类似的内容:
cdef extern from "lib.h":
cdef int CONST_A = 0
cdef int CONST_B = 1
当我编译扩展时,常量在 Python 中不可用。我尝试做这样的事情,但它似乎不起作用:
cdef extern from "lib.h":
cdef int CONST_A = 0
cdef int CONST_B = 1
CONST_A = CONST_A
CONST_B = CONST_B
关于如何使这些常量在 Python 中可用的任何想法?
【问题讨论】:
我认为您可以使用cpdef
而不是cdef
作为常量。
我试过了,还是不行。
github.com/cython/cython/commit/…
【参考方案1】:
你说得对,那里的 Cython 似乎有一个洞。
我可以声明cpdef int CONST_C = 3
,它可以编译,但在 Python 中不可见。这似乎是一个错误——如果它接受语法,它应该对它做一些合理的事情。
似乎确实有效的一件事是:
cpdef enum:
CONST_A = 0
CONST_B = 1
这可能对您的情况足够好,也可能不够好,但它似乎适用于许多用例——也许这就是没有注意到该错误的原因?
【讨论】:
【参考方案2】:我使用的解决方案很容易切换到“正确”的解决方案,一旦支持,就是在 .pyx 文件中以枚举名称为前缀重新声明枚举值,然后它们就很容易了发现。
所以在 foo.pxd 中:
cdef enum Mood:
happy
sad
然后在全局范围的 foo.pyx 中:
Mood_happy = happy
Mood_sad = sad
在 bar.py 中:
from foo import Mood_happy, Mood_sad
# do something with Mood_happy and Mood_sad as ints
【讨论】:
【参考方案3】:评论太晚了,但是下面的代码怎么样? 这个想法来源于How can a #defined C value be exposed to Python in a Cython module?
此解决方案在我的库中运行良好。 “CONST_A”和“CONST_B”是 cdef/cpdef 函数的别名。 在 Cython(.pyx) 中,它们可以用作宏。 要将宏暴露给 Python,需要 CONST_A = _CONST_A 和 CONST_B = _CONST_B。
a.pyx
cdef extern from "lib.h":
cdef int _CONST_A "CONST_A"
cdef int _CONST_B "CONST_B"
def use_const():
if CONST_A:
do_something()
if CONST_B:
do_something()
CONST_A = _CONST_A
CONST_B = _CONST_B
编译后可以在python代码中使用。
使用_a.py
import a
print(a.CONST_A)
print(a.CONST_B)
【讨论】:
以上是关于使用 Cython 从标头导出常量的主要内容,如果未能解决你的问题,请参考以下文章
PyArray_Check 使用 Cython/C++ 给出分段错误