You need to enable JavaScript to run this app. 使用Cython时如何传递C对象?报错Cannot convert Python object to class_name怎么办
优惠活动
大模型
产品
解决方案
定价
更多

使用Cython时如何传递C对象?报错Cannot convert Python object to class_name怎么办

问题背景

我准备了如下最小示例,其中C++类采用大写命名,Cython类采用小写命名。执行语句self.ip = new BCD(ob.ip[0].obj_abc)时收到报错Cannot convert Python object to 'ABC',但ip本身是class BCD的指针,且BCD类包含obj_abc成员。请问我该如何通过指针访问BCD中内置的obj_abc?

注:前三个定义存放在.pxd文件中,最后一个定义存放在.pyx文件中。

cdef cppclass ABC:
    ABC()
    
cdef cppclass BCD:
    ABC obj_abc
    BCD(ABC &)
    BCD()

cdef class bcd:
    cdef BCD * ip
            
cdef class bcd:
    def __cint__(self, ob=None):
        if ob is not None:
            self.ip = new BCD(ob.ip[0].obj_abc)
            # isinstance(ob, bcd) is True
        else:
            self.ip = new BCD()
解决方案

给__cint__方法的ob参数加上静态类型标注即可解决问题,将原定义行:
def __cint__(self, ob=None):
修改为:
def __cint__(self, bcd ob=None):

原理说明

未给ob加类型标注时,Cython会将其识别为通用Python对象,无法直接访问Cython扩展类bcd中用cdef声明的成员属性ip,访问ob.ip时会被当作Python属性查找,返回的是Python对象而非原生C指针指向的内容,后续取obj_abc时自然无法匹配C的ABC类型要求。加上bcd类型标注后,Cython会在编译阶段识别ob的静态类型,直接访问其原生C层级的ip成员,获取到正确的BCD指针,进而取出类型匹配的obj_abc成员传入构造函数。

内容的提问来源于stack exchange,提问作者Andrew Mathews

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 19:48:03