Cython编译错误C-Libraries教程

时间:2017-01-25 14:00:09

标签: python cython

我目前正在尝试学习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对象,但我真的不知道确切的问题是什么。

有人可以帮助我理解错误吗?

1 个答案:

答案 0 :(得分:1)

que.pyxque.pxd共享命名空间(如果pxd文件与pyx文件同名,则它会自动进入pyx文件)。因此,Cython认为Queue既是C结构定义又是cdef类。 (在这种情况下,您不需要cimport que

您已经(至少)有3个选项:

  1. 重命名其中一个文件(因此自动进入pyx命名空间并不会发生)。
  2. 重命名您的cdef类。
  3. 重命名您的C结构。请注意,您只需要在Cython中执行此操作,您可以将名称保留在C:
  4. 第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

    检查拼写。