Cython编译错误:无法将Python对象参数转换为类型'FooBar *

7 投票
1 回答
6067 浏览
提问于 2025-04-17 05:48

我正在使用 Cython(0.15.2)为 Python(2.6.5)创建一个扩展。我已经创建了一个 pxd 文件和一个 pyx 文件。以下是我的 pyx 文件的内容:

cimport capifuncs

cdef class myArray:
    cdef capifuncs.myArray *_my_array
    def __cinit__(self, size):
        self._my_array = capifuncs.array_new(size)
        if (self._my_array is NULL):
            raise MemoryError()

    def __dealloc__(self):
        if self._my_array is not NULL:
            capifuncs.array_free(self._my_array)

    def __bool__(self):
        return not capifuncs.IsEmpty(self._my_array)


    ##############################
    #        Array methods       #
    ##############################

    cpdef getItem(self, unsigned int pos):
        if capifuncs.IsEmpty(self._my_array):
            raise IndexError("Array is empty")
        #if ():
        #    raise IndexError("Array bounds exceeded")

        return capifuncs.array_get_item(self._my_array, pos)


    cpdef setItem(self, unsigned int pos, double val):
        if capifuncs.IsEmpty(self._my_array):
            raise IndexError("Array is empty")
        #if ():
        #    raise IndexError("Array bounds exceeded")

        capifuncs.array_set_item(self._my_array, pos, val)




# Free functions
cpdef long someCAPIFuncCall(capifuncs.FooBar *fb, capifuncs.myArray *arr, long start, long stop):
    return capifuncs.doSomethingInteresting(fb, arr, start, stop)

如果我把那个自由函数的定义注释掉,代码就能正确编译,并且生成扩展。但是,如果我把它取消注释并尝试编译这个文件,就会出现以下错误信息:

cafuncs.pyx:64:23: 无法将 Python 对象参数转换为类型 'FooBar *'

这是什么原因,应该怎么解决呢?

1 个回答

4

cpdef 定义的函数可以同时被 Python 和 C 调用。

如果你在函数中使用 C 的数据类型作为参数,当这个函数从 Python 被调用时,Cython 会尝试自动把传入的对象转换成相应的类型。不过,这种转换只对数字和字符串类型有效,其他类型会导致编译时出错。

你是想让这个函数在 Python 中可用吗?如果不是,应该用 cdef 来定义它。

否则,你需要为想要在 Python 和 C 之间传递的 C 类型创建一些包装器。想了解更多,可以查看 Cython 教程,里面有一些示例。

撰写回答