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

能否将SwigObject向下转型为具体类型?扩展Python端PtrRec识别

问题解答

结论:两种方案都可行,但修改C代码是更优选择

不需要强制修改C代码就能实现需求,但修改代码的方案更简洁、可维护;不修改代码的方案需要借助SWIG的包装技巧,相对繁琐。

方案一:不修改现有C代码,通过SWIG包装实现

利用SWIG的扩展机制和手动类型标记来区分两种实例:

  • 在SWIG接口文件中,对create_left和create_right的返回值进行包装,给每个返回的Ptr实例附加一个自定义类型标记(比如Python属性_type,值为"left"或"right")
  • 通过%extend为Ptr类型添加get_size方法,在方法内部根据实例的类型标记,调用对应C侧的内部大小获取函数(需要确保left.c和right.c能提供对应的接口,比如get_left_size(Ptr)和get_right_size(Ptr))
  • 示例SWIG代码片段:
    %include "mid.h"
    
    // 给create_left的返回值打标记
    %pythoncode %{
        original_create_left = create_left
        def create_left():
            ptr = original_create_left()
            ptr._type = "left"
            return ptr
    %}
    
    // 同理处理create_right
    %pythoncode %{
        original_create_right = create_right
        def create_right():
            ptr = original_create_right()
            ptr._type = "right"
            return ptr
    %}
    
    // 扩展get_size方法
    %extend Ptr {
        int get_size() {
            PyObject *type_attr = PyObject_GetAttrString($self, "_type");
            if (strcmp(PyUnicode_AsUTF8(type_attr), "left") == 0) {
                return get_left_size($self);
            } else if (strcmp(PyUnicode_AsUTF8(type_attr), "right") == 0) {
                return get_right_size($self);
            }
            PyErr_SetString(PyExc_TypeError, "Unknown Ptr type");
            return -1;
        }
    }
    
  • 这种方式的缺点是依赖手动标记类型,没有编译期类型安全,容易出错,维护成本高。

方案二:修改C代码(推荐)

通过重命名结构并显式暴露类型,让SWIG直接识别不同的指针类型:

  • 将left.c中的struct PtrRec重命名为struct LeftPtrRec,right.c中的重命名为struct RightPtrRec
  • 在mid.h中显式声明两种指针类型:
    typedef struct LeftPtrRec* LeftPtr;
    typedef struct RightPtrRec* RightPtr;
    
  • 修改left.c的create_left返回LeftPtr,right.c的create_right返回RightPtr
  • 在SWIG接口文件中,分别为LeftPtr和RightPtr添加%extend方法:
    %include "mid.h"
    
    %extend LeftPtr {
        int get_size() {
            return get_left_size($self);
        }
    }
    
    %extend RightPtr {
        int get_size() {
            return get_right_size($self);
        }
    }
    
  • 这种方式下,Python端会生成两个不同的类,直接通过类型判断就能区分实例,转型自然,类型安全,代码更清晰易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:47:55