【发布时间】:2018-01-20 07:11:43
【问题描述】:
使用最新更新的 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 中分布在多行上。该过程的目的是使用参数数组 args 调用方法 methodName。但是,我无法成功地将参数传递给调用的方法。尽管调用了正确的函数,但被调用方法的入口处的参数是乱码。我的问题是我应该如何将一个 T 数组传递给调用方法?
我也尝试使用调用调用
mt.Invoke(py, [args]);
但我得到编译错误:
E2250 没有可以使用这些参数调用的“Invoke”的重载版本。
试过了
mt.Invoke(py, [@args]);
但我得到运行时错误:
带有“Invalid case typecast”消息的 EInvalidCast,尝试跟踪调用,但未能成功找出错误的原因。
被调用端的代码是:
class function TPyArithmetic.add (args : PPyObjectArray) : double;
begin
result := TArithmetic.add (GetPythonEngine.PyFloat_AsDouble (args[0]), GetPythonEngine.PyFloat_AsDouble (args[1]));
end;
有什么建议吗?
【问题讨论】:
-
顺便说一句,我怀疑 PyObject 是否应该被打包。它不会影响布局,并且它们都是动态分配的,因此不会影响对齐。但是还是……
-
这些类型来自另一个第三方库。我想准确地展示其他库是如何定义这些类型的,以防它对问题产生影响。
-
当然。这是我不使用该库的原因之一。我不相信它。
-
除了大卫在他的回答中指出的明显缺陷之外,实际查看被调用方法的代码来判断通过 RTTI 的调用是否正在做它应该做的事情会很有帮助。
-
更新了问题以显示调用的代码。注意我还在探索这种做事方式,你看到的代码并不是最终的代码。