如何将指针类型数组传递给Delphi中的RttiMethods.Invoke

时间:2018-01-19 05:21:02

标签: delphi rtti

将Delphi 10.2与最新更新一起使用

我有一个程序(实际代码):

PyObject = packed record ... end;
PPyObject = ^PyObject
PPyObjectArray = array of PPyObject;

procedure invokeMethod (methodName : string; args : PPyObjectArray);
var  ctx: TRttiContext;
     rt : TRttiType;
     mt : TRttiMethod;
     py : TPyArithmetic;
     tv : array of TValue;
begin
   py := TPyArithmetic.Create;
   ctx := TRttiContext.Create;
   try
     rt := ctx.GetType(TPyArithmetic);
     mt := rt.GetMethod (methodName);

    setlength (tv, 1);
    tv[0].From(args);
    mt.Invoke(py, tv);
  finally
    ctx.Free;
  end;
end;

出于调试原因,代码本身在invokeMethod中展开到多行上。该过程的目的是使用参数array args调用方法methodName。但是,我无法成功地将参数传递给调用的方法。虽然调用了正确的函数,但是在调用方法的入口处的参数是乱码。我的问题是如何将一个T数组传递给invoke方法?

我也尝试使用

调用invoke

mt.Invoke(py,[args]);

但是我得到了编译错误:

E2250没有重载版本的'调用'可以使用这些参数调用。

尝试

mt.Invoke(py,[@ args]);

但是我收到了运行时错误:

EInvalidCast,带有消息'无效的案例类型转换',试图跟踪呼叫,但没有成功找出我收到错误的原因。

被调用方的代码是:

class function TPyArithmetic.add (args : PPyObjectArray) : double;
begin
   result := TArithmetic.add (GetPythonEngine.PyFloat_AsDouble (args[0]), GetPythonEngine.PyFloat_AsDouble (args[1]));
end;

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

TValue.From是一个返回新值的函数。这段代码错了:

tv[0].From(args);

没有任何内容分配给tv[0]。你需要这样做:

tv[0] := TValue.From(args);

更简单的方法是删除动态数组并使用开放数组构造函数:

mt.Invoke(py, [TValue.From(args)]);

创建和销毁RTTI上下文的代码也是虚假的。它的工作方式很好,但它同样可以:

procedure invokeMethod(methodName: string; args: PPyObjectArray);
var  
  ctx: TRttiContext;
  rt: TRttiType;
  mt: TRttiMethod;
  py: TPyArithmetic;
begin
  py := TPyArithmetic.Create;  
  rt := ctx.GetType(TPyArithmetic);
  mt := rt.GetMethod (methodName);
  mt.Invoke(py, [TValue.From(args)]);
end;

FWIW,您的代码看起来像是py