SWIG Directors未按预期工作:Python重写方法调用失败
解决SWIG中Python继承C++回调类后虚函数未被调用的问题
问题根源
你的代码存在两个核心问题:
%feature("director")声明顺序错误:SWIG要求%feature("director")必须放在目标类定义之前,否则无法生成正确的代理类,导致C++端无法将调用路由到Python的重写方法。- Python中错误使用
@override装饰器:Python标准库默认没有@override装饰器,未导入就直接使用会引发错误(即使没报错,它也不会影响方法重写逻辑)。
修正后的代码
1. 调整example.i文件
将%feature("director")移至类定义前:
%module(directors="1") example // 必须在CBack类定义前声明director特性 %feature("director") CBack; %inline %{ class CBack { public: virtual int operator()(int x, int y) const { return x+y; } virtual int handle(int x, int y) { return -1; } virtual ~CBack() {} }; int callF(CBack* f, int xv, int yv) { return f->handle(xv, yv); } %}
2. 修正example.py文件
移除未导入的@override装饰器(如需保留,需添加from typing import override),同时建议保存实例引用避免被Python垃圾回收过早销毁:
import example class Mul(example.CBack): def handle(self, x: int, y: int) -> int: return x * y # 保存实例引用,避免复杂场景下被GC回收 mul_instance = Mul() print(example.callF(mul_instance, 3, 7)) # 现在输出21 print(str(Mul().handle(3,7))) # 输出21
额外注意事项
- 编译SWIG时需确保启用C++和Python支持,命令示例:
swig -c++ -python example.i,后续正常编译链接生成扩展模块即可。 - 若要使用
@override装饰器,需在Python文件开头添加from typing import override,它仅做静态检查,用于验证是否正确重写父类方法,不影响运行逻辑。
内容的提问来源于stack exchange,提问作者Stav Faran
相关产品推荐
相关产品推荐

