简体   繁体   English

使用Cython从标题导出常量

[英]Export constants from header with Cython

I'm using Cython to wrap a C library. 我正在使用Cython来包装C库。 The C library's header file defines a number of constants, so in my cython module, I have something like: C库的头文件定义了许多常量,所以在我的cython模块中,我有类似的东西:

cdef extern from "lib.h":
    cdef int CONST_A = 0
    cdef int CONST_B = 1

When I compile the extension, the constants are not available in Python. 当我编译扩展时,常量在Python中不可用。 I tried doing something like this, but it did not seem to work: 我尝试过这样的事情,但似乎没有用:

cdef extern from "lib.h":
    cdef int CONST_A = 0
    cdef int CONST_B = 1

CONST_A = CONST_A
CONST_B = CONST_B

Any ideas on how to make these constants available in Python? 关于如何在Python中提供这些常量的任何想法?

You're right in that there seems to be a hole in Cython there. 你是对的,那里似乎有一个洞在Cython那里。

I can declare cpdef int CONST_C = 3 and it compiles but isn't visible from Python. 我可以声明cpdef int CONST_C = 3并且它编译但是从Python cpdef int CONST_C = 3不到。 That would seem to be a bug -- if it accepts the syntax, it should do something reasonable with it. 这似乎是一个错误 - 如果它接受语法,它应该做一些合理的事情。

One thing that did seem to work is this: 似乎有用的一件事是:

cpdef enum:
    CONST_A = 0
    CONST_B = 1

That may or may not be good enough for your case, but it seems it would work well for many use-cases -- maybe it's why the bug wasn't noticed? 对于你的情况,这可能或者可能不够好,但似乎它适用于许多用例 - 也许这就是为什么没有注意到这个bug?

The solution I use which would be fairly easy to then switch to the "right" solution once supported is to re-declare the enum values one by one in the .pyx file prefixed by the enum's name, then they are quite easy to spot. 我使用的解决方案一旦支持就很容易切换到“正确”的解决方案是在.pyx文件中逐个重新声明枚举值,前缀为enum的名称,然后它们很容易被发现。

So in foo.pxd: 所以在foo.pxd中:

cdef enum Mood:
    happy
    sad

Then in foo.pyx at global scope: 然后在全局范围的foo.pyx中:

Mood_happy = happy
Mood_sad = sad

And in bar.py: 并在bar.py:

from foo import Mood_happy, Mood_sad

# do something with Mood_happy and Mood_sad as ints

Too late comment but how about the following code ? 评论太迟了但是下面的代码怎么样? This idea is derived from How can a #defined C value be exposed to Python in a Cython module? 这个想法来自于如何在Cython模块中将#defined C值暴露给Python?

This solution works well in my library. 此解决方案在我的库中运行良好。 "CONST_A" and "CONST_B" are alias for cdef/cpdef functions. “CONST_A”和“CONST_B”是cdef / cpdef函数的别名。 In of Cython(.pyx), they can be used as a macro. 在Cython(.pyx)中,它们可以用作宏。 To expose macro to Python, CONST_A = _CONST_A and CONST_B = _CONST_B are needed. 要将宏公开给Python,需要CONST_A = _CONST_A和CONST_B = _CONST_B。

a.pyx 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

After compile, you can use them in python code. 编译后,您可以在python代码中使用它们。

use_a.py use_a.py

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM