【问题标题】:Export constants from header with Cython使用 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 中可用的任何想法?

【问题讨论】:

标签: python c cython


【解决方案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)
      

      【讨论】:

        猜你喜欢
        • 2021-10-08
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 2017-11-12
        • 2011-01-20
        • 1970-01-01
        相关资源
        最近更新 更多