Reputation: 163
I am currently trying to learn Cython, and started by going through their Tutorial. (Running Debian 8) I am running into problems in the Using C libraries part.
Here are my 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)
and 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)
When I try to do python setup.py build_ext -i
it tells me the following error messages:
Compiling que.pyx because it changed.
[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
To me it seems like the main problems are that I redeclare some things and that a pointer cannot be converted into a python object, but I really do not know what the exact problem is.
Can somebody help me make sense of the errors?
Upvotes: 0
Views: 1509
Reputation: 30891
que.pyx
and que.pxd
share a namespace (if a pxd file has the same name as a pyx file then it's automatically cimported into the pyx file). Therefore Cython believes Queue
to be both the C structure definition and your cdef class. (Under these circumstances you don't need to do cimport que
)
You've got (at least) 3 options:
Code for point 3:
ctypedef struct c_Queue "Queue": # called c_Queue in Cython but Queue in C
pass
You then end up with a bunch of minor error messages:
que.pyx:6:38: Cannot convert Python object to 'Queue *'
Check the spelling of que.cqueue_new()
que.pyx:11:21: Invalid types for 'is_not' (Python object, void *)
You can't use is not
for C pointers. Use !=
que.pyx:12:14: undeclared name not builtin: cqueue
Check the spelling.
Upvotes: 1