我目前正在尝试学习Cython,并开始学习他们的教程。 (运行Debian 8) 我在Using C libraries部分遇到了问题。
这是我的setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules = cythonize([
Extension("queue", ["que.pyx"],
libraries=["calg"])
])
setup(
ext_modules=ext_modules )
que.pxd
cdef extern from "libcalg/queue.h":
ctypedef struct Queue:
pass
ctypedef void* QueueValue
Queue* queue_new()
void queue_free(Queue* queue)
int queue_push_head(Queue* queue, QueueValue data)
QueueValue queue_pop_head(Queue* queue)
QueueValue queue_peek_head(Queue* queue)
int queue_push_tail(Queue* queue, QueueValue data)
QueueValue queue_pop_tail(Queue* queue)
QueueValue queue_peek_tail(Queue* queue)
bint queue_is_empty(Queue* queue)
和que.pyx
cimport que
cdef class Queue:
cdef que.Queue* _c_queue
def __cinit__(self):
self._c_queue = que.cqueue_new()
if self._c_queue is NULL:
raise MemoryError()
def __dealloc__(self):
if self._c_queue is not NULL:
cqueue.queue_free(self._c_queue)
当我尝试python setup.py build_ext -i
时,它会告诉我以下错误消息:
编译que.pyx,因为它已更改。
[1/1] Cythonizing que.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cimport que
cdef class Queue:
^
------------------------------------------------------------
que.pyx:3:5: 'Queue' redeclared
Error compiling Cython file:
------------------------------------------------------------
...
cimport que
cdef class Queue:
cdef que.Queue* _c_queue
^
------------------------------------------------------------
que.pyx:4:18: Pointer base type cannot be a Python object
Error compiling Cython file:
------------------------------------------------------------
...
cimport que
cdef class Queue:
cdef que.Queue* _c_queue
def __cinit__(self):
self._c_queue = que.cqueue_new()
^
------------------------------------------------------------
que.pyx:6:38: Cannot convert Python object to 'Queue *'
Error compiling Cython file:
------------------------------------------------------------
...
cimport que
cdef class Queue:
cdef que.Queue* _c_queue
def __cinit__(self):
self._c_queue = que.cqueue_new()
^
------------------------------------------------------------
que.pyx:6:38: Storing unsafe C derivative of temporary Python reference
Error compiling Cython file:
------------------------------------------------------------
...
self._c_queue = que.cqueue_new()
if self._c_queue is NULL:
raise MemoryError()
def __dealloc__(self):
if self._c_queue is not NULL:
^
------------------------------------------------------------
que.pyx:11:21: Invalid types for 'is_not' (Python object, void *)
Error compiling Cython file:
------------------------------------------------------------
...
if self._c_queue is NULL:
raise MemoryError()
def __dealloc__(self):
if self._c_queue is not NULL:
cqueue.queue_free(self._c_queue)
^
------------------------------------------------------------
que.pyx:12:14: undeclared name not builtin: cqueue
Traceback (most recent call last):
File "setup.py", line 7, in <module>
libraries=["calg"])
File "/usr/local/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 877, in cythonize
cythonize_one(*args)
File "/usr/local/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 997, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: que.pyx
对我来说,似乎主要的问题是我重新声明了一些东西并且指针无法转换为python对象,但我真的不知道确切的问题是什么。
有人可以帮助我理解错误吗?
答案 0 :(得分:1)
que.pyx
和que.pxd
共享命名空间(如果pxd文件与pyx文件同名,则它会自动进入pyx文件)。因此,Cython认为Queue
既是C结构定义又是cdef类。 (在这种情况下,您不需要cimport que
)
您已经(至少)有3个选项:
第3点的代码:
ctypedef struct c_Queue "Queue": # called c_Queue in Cython but Queue in C
pass
然后你会收到一堆小错误信息:
que.pyx:6:38: Cannot convert Python object to 'Queue *'
检查que.cqueue_new()
que.pyx:11:21: Invalid types for 'is_not' (Python object, void *)
您不能将is not
用于C指针。使用!=
que.pyx:12:14: undeclared name not builtin: cqueue
检查拼写。