Cython compiling error: Saying that Array is a Struct
Cython compiling error: Saying that Array is a Struct
这是我的 Cython 错误的最小可重现版本。代码在 C++ 中运行。
编译器告诉我错误 C2088“+= 对于结构是非法的”。但是,它正在传递一个数组。
pyx 文件:
from libc.stdint cimport uint32_t as Card
from cpython cimport array
import array
cdef extern from "ace_eval.h":
void ACE_addcard(h, Card c)
def create_hand():
cdef array.array h = array.array('I',[0, 0, 0, 0, 0])
ACE_addcard(h, 257)
return h
从header导入的函数是:
#define ACE_addcard(h,c) h[c&7]+=c,h[3]|=c
我也尝试过使用声明我的数组
cdef Card h[5]
array.array
是一个 Python 对象,它最终被编译成一个结构(所以这是 C++ 看到的)。对它的元素访问由 __getitem__
和 __setitem__
在 Python 级别控制,它们由 Cython 编译成 C API 函数调用。当 Cython 看到正在操作的数组的代码时,它将生成适当的 C API 函数调用。您使用 C++ #define
语句编写代码,试图在 C++ 编译时对其进行操作,并阻止 Cython 知道发生了什么。
理想情况下,您应该使用 "typed memoryviews" 来让 Cython 更快地访问数组(但是 仍然 不能与 C++ #define
一起工作,因为这是在 Cython 处理完文件后应用):
cdef int[::1] h = array.array('I',[0, 0, 0, 0, 0]) # you may have to change the type long... I haven't tested it
h[257&7]+=257
h[3]|=257
如果您绝对坚持使用宏,那么他们需要使用 C++ 数组接口。指针可能是最简单的选择,可以从以下位置获得:
cdef int* h_ptr = &h[0]
@DavidW的第二种方式
cdef Card h[5]
h[:] = [0, 0, 0, 0, 0]
cdef Card* h_ptr = &h[0]
我也像这样调整了我的 cdef 以接受指针后,它也起作用了。请注意,#define 宏中的函数未更改且未指定 return 类型。
cdef extern from "ace_eval.h":
void ACE_addcard(Card* h, Card c)
这让我可以完美地传递我的任何数组。
这实际上是文档中所说的,但对我来说有点迟钝 - 希望我的解释对其他人有所帮助。
https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html
If the header file defines a function using a macro, declare it as though it were an ordinary function, with appropriate argument and result types.
这是我的 Cython 错误的最小可重现版本。代码在 C++ 中运行。
编译器告诉我错误 C2088“+= 对于结构是非法的”。但是,它正在传递一个数组。
pyx 文件:
from libc.stdint cimport uint32_t as Card
from cpython cimport array
import array
cdef extern from "ace_eval.h":
void ACE_addcard(h, Card c)
def create_hand():
cdef array.array h = array.array('I',[0, 0, 0, 0, 0])
ACE_addcard(h, 257)
return h
从header导入的函数是:
#define ACE_addcard(h,c) h[c&7]+=c,h[3]|=c
我也尝试过使用声明我的数组
cdef Card h[5]
array.array
是一个 Python 对象,它最终被编译成一个结构(所以这是 C++ 看到的)。对它的元素访问由 __getitem__
和 __setitem__
在 Python 级别控制,它们由 Cython 编译成 C API 函数调用。当 Cython 看到正在操作的数组的代码时,它将生成适当的 C API 函数调用。您使用 C++ #define
语句编写代码,试图在 C++ 编译时对其进行操作,并阻止 Cython 知道发生了什么。
理想情况下,您应该使用 "typed memoryviews" 来让 Cython 更快地访问数组(但是 仍然 不能与 C++ #define
一起工作,因为这是在 Cython 处理完文件后应用):
cdef int[::1] h = array.array('I',[0, 0, 0, 0, 0]) # you may have to change the type long... I haven't tested it
h[257&7]+=257
h[3]|=257
如果您绝对坚持使用宏,那么他们需要使用 C++ 数组接口。指针可能是最简单的选择,可以从以下位置获得:
cdef int* h_ptr = &h[0]
@DavidW的第二种方式
cdef Card h[5]
h[:] = [0, 0, 0, 0, 0]
cdef Card* h_ptr = &h[0]
我也像这样调整了我的 cdef 以接受指针后,它也起作用了。请注意,#define 宏中的函数未更改且未指定 return 类型。
cdef extern from "ace_eval.h":
void ACE_addcard(Card* h, Card c)
这让我可以完美地传递我的任何数组。
这实际上是文档中所说的,但对我来说有点迟钝 - 希望我的解释对其他人有所帮助。 https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html
If the header file defines a function using a macro, declare it as though it were an ordinary function, with appropriate argument and result types.