我想将以下代码包装在 cython 中:
enum Status {GOOD, BAD};
typedef enum Status STATUS;
// note that the typedef means people dont
// have to write `enum Status` everywhere
// just returns `GOOD`
STATUS hello();
我在中编写了以下 cython 代码c_library.pxd
:
cdef extern from "library.h":
cpdef enum Status:
GOOD,
BAD
ctypedef Status STATUS
cpdef STATUS hello()
该模块c_library
现在包含c_library.GOOD
, c_library.BAD
,
and c_library.Status
,其行为类似于enum https://www.python.org/dev/peps/pep-0435/。但是,那
函数调用的返回值hello
返回一个普通的 int:
>>> c_library.hello()
0
>>> type(c_library.hello())
<class 'int'>
我希望结果也包含在相同类型的枚举中。
我可以更改 cython 文件,但不能更改底层 C 代码。那可能吗?
这看起来像是 Cython 的一个小问题(小错误?),它决定使用__Pyx_PyInt_From_enum__
包装时由于某些原因cdef
-函数变成def
功能。
作为一种快速解决方法,我可以建议明确创建一个Status
-enum:
%%cython
cdef extern from *:
"""
typedef enum Status {GOOD, BAD} Status;
// just returns `GOOD`
Status hello() {return GOOD;}
"""
cpdef enum Status:
GOOD,
BAD
Status c_hello "hello"()
def hello():
return Status(c_hello())
And now:
>>> type(hello())
<enum 'Status'>
可能值得注意的事情:
-
逐字 C 代码 https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#including-verbatim-c-code使用,使示例独立。
- Using
typedef enum X {...} X;
将枚举的类型名称从枚举的名称空间拉入普通变量的名称空间是一种常见的做法(但显然这是一个品味问题,所以如果您愿意STATUS
- 它是由你决定)。请参阅 C11 标准中关于不同名称空间的措辞here http://port70.net/~nsz/c/c11/n1570.html#6.2.3或这个很好的答案 https://stackoverflow.com/a/612350/5769463(即使是关于struct
).
-
cname
-技巧(即Status c_hello "hello"()
使用 ) 是为了能够添加间接级别并保持模块的公共接口完整(即cpdef hello()
).
- 然而,当使用
hello
as cdef
-我可能会使用的功能c_hello
避免创建枚举的开销 - 这就是原因hello()
被定义为def
- 功能,所以不会造成混乱。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)