PyDelphiWrapper封装的Delphi函数参数始终为固定错误值如何解决?
问题原因
这个问题的核心是PyDelphiWrapper对record结构下的静态类方法参数解析异常,结合你用的Delphi Seattle版本的Rtti特性,具体触发逻辑如下:
- 你将
count_primes定义为TDelphiFunctionsrecord的静态类方法(加了class和static修饰),但WrapRecord接口默认是用来封装record实例成员的,会默认把record实例的指针作为第一个隐式参数传递给成员方法 - 低版本Delphi(Seattle及更早)的Rtti不会明确标记静态类方法不需要隐式self参数,导致Python4Delphi解析参数顺序时出错:你从Python传入的
1000000被识别为第二个参数,而第一个参数MaxN拿到的实际是DelphiFunctions这个全局record变量的内存地址,也就是你看到的固定值8574564。
解决方案
方案1(最稳妥,兼容性最好):直接注册全局函数到Python模块,放弃WrapRecord封装静态方法
- 保留
TDelphiFunctions的业务代码,新增Python调用适配函数,通过PythonModule.AddMethod直接注册:
// 新增Python调用适配函数,cdecl调用约定是必须的 function Py_CountPrimes(Self: PPyObject; Args: PPyObject): PPyObject; cdecl; var MaxN: Integer; begin // 解析Python传入的整数参数 if not GetPythonEngine.PyArg_ParseTuple(Args, 'i:count_primes', @MaxN) then Exit(nil); // 调用原有业务逻辑,返回结果给Python Result := GetPythonEngine.PyLong_FromLong(TDelphiFunctions.count_primes(MaxN)); end; procedure TForm1.FormCreate(Sender: TObject); begin // 删掉原来的WrapRecord相关代码,改用下面的方式注册函数 PythonModule.AddMethod('count_primes', @Py_CountPrimes, '统计小于等于MaxN的质数数量'); end;
- Python代码中直接调用
你的模块名.count_primes(1000000)即可。
方案2:调整record方法定义,避免静态类方法
如果需要保留record封装结构,把class和static修饰符去掉,改成普通的record成员方法:
type TDelphiFunctions = record function count_primes(MaxN: integer): integer; // 去掉class和static end;
调整后WrapRecord就能正确识别参数顺序,不会把record实例指针当成入参传递。
方案3:升级Delphi版本
如果可以升级开发环境,将Delphi升级到10.4 Sydney及以上版本,新版本的RTTI对静态类方法的标记更完善,配合最新版Python4Delphi可以自动正确处理参数解析,不需要修改业务代码。
内容的提问来源于stack exchange,提问作者Jo. D.
相关产品推荐
相关产品推荐

