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

如何通过Cython将自定义C++ Message类对象转换为Python对象?

解决C++ Message类转Python对象的Cython编译错误

错误原因

Cython无法自动将C++的Message&转换为Python对象,因为你仅在Cython中声明了cppclass Message,但没有定义任何将其映射到Python类型的规则。

解决方案

方案1:将Message包装为Python扩展类

通过在Cython中定义一个Python类,内部持有Message实例,暴露其方法/属性给Python层。

假设你的Message类有如下成员(需根据实际Streaming.h中的定义调整):

class Message {
public:
    int get_id() const;
    std::string get_content() const;
};

修改Streaming_test.pyx如下:

from libcpp.vector cimport vector
from libcpp.string cimport string

# 声明Message类的成员函数
cdef extern from "Streaming.h":
    cdef cppclass Message:
        Message() except +
        int get_id() const
        string get_content() const

cdef extern from "test.h":
    vector[Message] subscribe_(const string taskid) nogil

# 定义Python包装类
cdef class PyMessage:
    cdef Message* msg_ptr  # 持有Message实例指针
    def __cinit__(self):
        self.msg_ptr = new Message()
    def __dealloc__(self):
        del self.msg_ptr
    # 暴露get_id方法
    def get_id(self):
        return self.msg_ptr.get_id()
    # 暴露get_content方法
    def get_content(self):
        return self.msg_ptr.get_content()

def __subscribe(string taskid):
    cdef vector[Message] vecMsg
    listMsg = []
    vecMsg = subscribe_(taskid)
    for i in range(vecMsg.size()):
        # 创建PyMessage实例,将C++ Message对象赋值给它
        cdef PyMessage py_msg = PyMessage()
        del py_msg.msg_ptr
        py_msg.msg_ptr = new Message(vecMsg[i])
        listMsg.append(py_msg)
    return listMsg

方案2:提取Message属性转为Python原生结构

如果不需要完整包装类,仅需将Message的数据转为Python字典/元组,直接在循环中提取属性:

from libcpp.vector cimport vector
from libcpp.string cimport string

cdef extern from "Streaming.h":
    cdef cppclass Message:
        Message() except +
        int get_id() const
        string get_content() const

cdef extern from "test.h":
    vector[Message] subscribe_(const string taskid) nogil

def __subscribe(string taskid):
    cdef vector[Message] vecMsg
    listMsg = []
    vecMsg = subscribe_(taskid)
    for i in range(vecMsg.size()):
        cdef Message& msg = vecMsg[i]
        # 提取属性转为Python字典
        msg_dict = {
            "id": msg.get_id(),
            "content": msg.get_content()
        }
        listMsg.append(msg_dict)
    return listMsg

注意事项

  • 上述代码中的get_id()、get_content()需替换为Message类实际的成员函数或属性。
  • 如果Message类有复杂的成员(如其他自定义类),需要递归处理这些成员的转换。
  • 若使用方案1,需确保Message类支持拷贝构造或移动构造,否则需要调整实例的创建方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:37:41