You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Cython访问封装C++对象的成员变量时编译报错求助

步骤1:新增pyperson.pxd文件

你需要将PyPerson的Cython类型声明放到独立的pxd文件中,这样其他pyx文件才能识别PyPerson作为Cython类型使用,文件内容如下:

from cperson cimport Person

cdef class PyPerson:
    # 声明c_person为Person类型指针,方便共享同一个C++实例
    cdef Person* c_person

步骤2:修改pyperson.pyx适配指针存储

调整PyPerson的实现,改为存储Person指针,避免对象拷贝导致的数值不同步问题:

# distutils: language = c++
from cperson cimport Person
from libcpp.memory cimport new, delete

cdef class PyPerson:
    def __cinit__(self, int id):
        # 堆上创建Person实例,生命周期与PyPerson绑定
        self.c_person = new Person(id)
    
    def __dealloc__(self):
        # 释放堆内存避免泄漏
        if self.c_person != NULL:
            delete self.c_person

    def get_id(self):
        return self.c_person.getId()
        
    def set_id(self, int id):
        self.c_person.setId(id)

步骤3:修改pygroup.pyx解决编译错误

调整导入逻辑、参数类型和返回逻辑:

# distutils: language = c++
from cperson cimport Person
from cgroup cimport Group
# 从pyperson的pxd文件cimport PyPerson类型
from pyperson cimport PyPerson

cdef class PyGroup:
    cdef Group c_group

    def __cinit__(self, PyPerson leader):
        # 接收Python层传入的PyPerson实例,取其内部的Person引用传参
        self.c_group = Group(leader.c_person[0])

    def get_leader(self):
        cdef PyPerson res = PyPerson.__new__(PyPerson)
        # 直接复用Group返回的Person指针,不做拷贝
        res.c_person = self.c_group.getLeader()
        return res
        
    def set_leader(self, PyPerson leader):
        self.c_group.setLeader(leader.c_person[0])

步骤4:修复测试代码笔误

你示例中的测试代码有笔误,my.group改为my_group即可:

from pyperson import PyPerson
from pygroup import PyGroup

nancy = PyPerson(7) # Create new person with id=7
my_group = PyGroup(nancy) # Create new group with leader=nancy
my_group.get_leader().set_id(12)
print(nancy.get_id())

重新执行python3 setup.py build_ext --inplace编译后运行测试代码,即可得到预期输出12。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:57:02