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