使用Cython从标题导出常量

时间:2015-08-01 21:06:22

标签: python c cython

我正在使用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中提供这些常量的任何想法?

3 个答案:

答案 0 :(得分:5)

你是对的,因为Cython中似乎有一个漏洞。

我可以声明-并且它编译但是从Python中看不到。这似乎是一个错误 - 如果它接受语法,它应该做一些合理的事情。

似乎有效的一件事是:

cpdef int CONST_C = 3

对于你的情况,这可能会或者可能不够好,但似乎它适用于许多用例 - 也许这就是为什么这个bug没有被注意到?

答案 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

答案 2 :(得分:0)

评论太晚了,但是下面的代码呢? 这个想法源自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代码中使用它们。

use_a.py

import a
print(a.CONST_A)
print(a.CONST_B)