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

PyDelphiWrapper封装的Delphi函数参数始终为固定错误值如何解决?

问题原因

这个问题的核心是PyDelphiWrapper对record结构下的静态类方法参数解析异常,结合你用的Delphi Seattle版本的Rtti特性,具体触发逻辑如下:

  1. 你将count_primes定义为TDelphiFunctions record的静态类方法(加了class和static修饰),但WrapRecord接口默认是用来封装record实例成员的,会默认把record实例的指针作为第一个隐式参数传递给成员方法
  2. 低版本Delphi(Seattle及更早)的Rtti不会明确标记静态类方法不需要隐式self参数,导致Python4Delphi解析参数顺序时出错:你从Python传入的1000000被识别为第二个参数,而第一个参数MaxN拿到的实际是DelphiFunctions这个全局record变量的内存地址,也就是你看到的固定值8574564。

解决方案

方案1(最稳妥,兼容性最好):直接注册全局函数到Python模块,放弃WrapRecord封装静态方法

  1. 保留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;
  1. 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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:15:02