Cython 将扩展模块传递给 python 导致 to_py_call_code 错误

Posted

技术标签:

【中文标题】Cython 将扩展模块传递给 python 导致 to_py_call_code 错误【英文标题】:Cython passing extension modules to python reults in to_py_call_code error 【发布时间】:2017-03-02 02:44:35 【问题描述】:

我刚刚开始熟悉 Cython,试图将一些类从 C++ 库包装到 Python 方法和类。我不太明白的是如何将这些扩展模块传递到 python 世界中。

这是我的pyx 文件中的代码 sn-p,它试图公开 c++ 类和方法:

# distutils: language = c++
# distutils: sources = Demuxer.cpp, SharedUtil.cpp, ffmpeg_tpl.c, tpl.c
# distutils: libraries = spam eggs
# distutils: include_dirs = /opt/food/include

from cython.operator cimport dereference as deref

cdef extern from "Demuxer.h":
    cdef cppclass DemuxPkt:
        int streamID
        int tb_num
        int tb_den
        bint splitPoint     
        int ts
        int duration 
        unsigned char* data
        DemuxPkt()
    int initDemuxWithFileImpl(char*)
    int getNextChunkImpl(DemuxPkt*)

以下是尝试将它们包装到python世界中的代码sn-p

cdef class Demuxer:

    def __cinit__(self, fname, stream=None, length=None):
        #if stream is not None and length is not None:
         #   initDemuxWithFileImpl(stream, length)
        #else:
        initDemuxWithFileImpl(fname)

    cpdef getNextChunk(self):
        cdef DemuxPacket _dpkt = DemuxPacket()
        getNextChunkImpl(_dpkt._thisptr) # Is this correct??
        return _dpkt


cdef class DemuxPacket(object):

    """A packet of encoded data 
    """
    cdef DemuxPkt* _thisptr
    def __cinit__(self, flag):
        #if flag is _cinit_bypass_sentinel:
        #    return
        self._thisptr = new DemuxPkt()
        if self._thisptr == NULL:
            raise MemoryError()

    def __dealloc__(self):
        if self._thisptr != NULL:
            del self._thisptr

    def __call__(self):
        return deref(self._thisptr)()

    cpdef long getMillisecondsTs(self):
        return (self._thisptr.ts*self._thisptr.tb_num)/(self._thisptr.tb_den/1000)

    cpdef long getMillisecondsDuration(self):
        return (self._thisptr.duration*self.struct.tb_num)/(self._thisptr.tb_den/1000)

但是,当我运行 cython 时,会出现以下错误:

AttributeError: 'ErrorType' object has no attribute 'to_py_call_code'

我对消息一无所知,也不知道如何推进。我在 Ubuntu 14.0.4 上使用的 Cython 版本是 0.25.2。

欢迎提出任何建议!!

提前致谢!!

【问题讨论】:

【参考方案1】:

问题出在__call__。您尝试使用DemuxPkt::operator(),但您还没有告诉 Cython。将其添加到cppclass 定义中:

cdef extern from "Demuxer.h":
    cdef cppclass DemuxPkt:
        # .. everything else unchanged
        int operator()()

我猜到返回类型是int。显然这可能不是真的,所以改变它以匹配真正的返回类型。

【讨论】:

以上是关于Cython 将扩展模块传递给 python 导致 to_py_call_code 错误的主要内容,如果未能解决你的问题,请参考以下文章

将 cython 函数与 cython 方法传递给 scipy.integrate

继承自 int 的 Cython 扩展类型导致 MemoryError

如何使用 cython 将 python 类公开给 c++

初用Cython编写扩展模块

将多个子模块折叠成一个 Cython 扩展

如何将内置的 Cython 扩展从 PC 转移到另一台?