- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 RTTI TRttiMethod.Invoke、stdcall 和 const 参数有疑问:
obj := TClassRecordTest.Create;
try
b.a := 10; b.b := 100;
a.a := 1; a.b := 2;
writeln('b.a='+IntToStr(b.a)+' b.b='+IntToStr(b.b));
writeln;
writeln('call test1');
writeln('a.a='+IntToStr(a.a)+' a.b='+IntToStr(a.b));
r := VToRec(RTTICall(obj, 'Test1', @a, @b));
writeln('test1 r.a='+IntToStr(r.a)+' r.b='+IntToStr(r.b));
a.a := 2; a.b := 3;
writeln('call test2');
writeln('a.a='+IntToStr(a.a)+' a.b='+IntToStr(a.b));
r := VToRec(RTTICall(obj, 'Test2', @a, @b));
writeln('test3 r.a='+IntToStr(r.a)+' r.b='+IntToStr(r.b));
a.a := 3; a.b := 4;
writeln('call test3');
writeln('a.a='+IntToStr(a.a)+' a.b='+IntToStr(a.b));
r := VToRec(RTTICall(obj, 'Test3', @a, @b));
writeln('test3 r.a='+IntToStr(r.a)+' r.b='+IntToStr(r.b));
a.a := 4; a.b := 5;
writeln('call test4');
writeln('a.a='+IntToStr(a.a)+' a.b='+IntToStr(a.b));
r := VToRec(RTTICall(obj, 'Test4', @a, @b));
writeln('test4 r.a='+IntToStr(r.a)+' r.b='+IntToStr(r.b));
finally
obj.Destroy;
end;
RTTI调用它是:
function RTTICall(aObj: TObject; MethodName: string; a, b: pointer): TValue;
var
RttiContext: TRttiContext;
ClassType: TRttiType;
Methods: TMethodList;
Method: TRttiMethod;
Params: TParamList;
Args: TArgList;
begin
RttiContext := TRttiContext.Create;
try
ClassType := FindFirstClassTypeByName(RttiContext, aObj.ClassName);
if ClassType <> nil then
begin
Methods := ClassType.GetDeclaredMethods;
for Method in Methods
do begin
if SameText(Method.Name, MethodName) then
begin
Params := Method.GetParameters;
SetLength(Args, Length(Params));
TValue.Make(nil, Params[0].ParamType.Handle, Args[0]);
move(a^, Args[0].GetReferenceToRawData^, Params[0].ParamType.TypeSize);
TValue.Make(nil, Params[1].ParamType.Handle, Args[1]);
move(b^, Args[1].GetReferenceToRawData^, Params[1].ParamType.TypeSize);
Result := Method.Invoke(TObject(aObj), Args);
exit;
end;
end;
end;
finally
// FreeAndNil(aObj);
end;
end;
和函数 TestN:
function TClassRecordTest.Test1(a, b: TRecordTest): TRecordTest;
begin
result.a := a.a+b.a;
result.b := a.b+b.b;
end;
function TClassRecordTest.Test2(var a, b: TRecordTest): TRecordTest;
begin
result.a := a.a+b.a;
result.b := a.b+b.b;
end;
function TClassRecordTest.Test3(const a, b: TRecordTest): TRecordTest;
begin
result.a := a.a+b.a;
result.b := a.b+b.b;
end;
function TClassRecordTest.Test4(const a, b: TRecordTest): TRecordTest;
begin
result.a := a.a+b.a;
result.b := a.b+b.b;
end;
结果是:
>Project7.exe
b.a=10 b.b=100
call test1
a.a=1 a.b=2
test1 r.a=11 r.b=102
call test2
a.a=2 a.b=3
test3 r.a=12 r.b=103
call test3
a.a=3 a.b=4
test3 r.a=13 r.b=104
call test4
a.a=4 a.b=5
EAccessViolation: Access violation at address 0047A65A in module 'Project7.exe'. Read of address 00000004
仅当用作 const 和 stdcall 参数时才会出现此错误。
如果我更改 Test3 和 Test4:
function TClassRecordTest.Test3(const a, b: TRecordTest): TRecordTest;
begin
writeLn('@a='+IntToStr(integer(@a))+' @b='+IntToStr(integer(@a)));
result.a := a.a+b.a;
result.b := a.b+b.b;
end;
function TClassRecordTest.Test4(const a, b: TRecordTest): TRecordTest;
begin
writeLn('@a='+IntToStr(integer(@a))+' @b='+IntToStr(integer(@a)));
result.a := a.a+b.a;
result.b := a.b+b.b;
end;
结果是:
>Project7.exe
b.a=10 b.b=100
call test1
a.a=1 a.b=2
test1 r.a=11 r.b=102
call test2
a.a=2 a.b=3
test3 r.a=12 r.b=103
call test3
a.a=3 a.b=4
@a=31301448 @b=31301448
test3 r.a=13 r.b=104
call test4
a.a=4 a.b=5
@a=4 @b=4
EAccessViolation: Access violation at address 0047A76C in module 'Project7.exe'. Read of address 00000004
事实证明,TRttiMethod.Invoke const 按值传递,尽管需要传递地址
最佳答案
你也遇到了和我一样的问题。让我引用巴里的话:
This is by design; the Rtti.Invoke function is at too low a level on the stack, and has no access to any typeinfo that could tell it whether to pass arguments by reference or by value. It expects all parameters to be converted to the correct type, including any by-ref parameters being converted to pointers as needed. All it does is stuff the values into registers and/or stack as required, invoke, and retrieve the return value (if any) from the appropriate location.
因此,为了传递 const、out 和 var 参数,您需要使用 TValue.From
关于delphi - RTTI TRttiMethod.Invoke、stdcall 和 const 参数的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6421674/
我有以下代码: Public Delegate Sub SetStatusBarTextDelegate(ByVal StatusText As String) Private Sub SetStat
在调用 Invoke-RestMethod 时使用 Powershell,例如: Invoke-RestMethod -Method Get -Uri "https://google.com/api/
我正在尝试将 Winform 应用程序转换为控制台应用程序。 Winform 应用程序有一个委托(delegate)处理程序。如何在 console 应用程序中编写相同的功能? this.Invoke
在 WPF 中,Dispatcher.Invoke 和直接在控件实例上调用的 Invoke 有什么区别。据我了解,调度程序负责处理线程的消息,Control.Invoke 是否会继续调用 Dispat
我正在研究性能监控系统,它可以将其例程注入(inject)现有程序集。为此,我试图了解 dalvik 代码的工作原理。 下面是我要完成的工作的示例。输入类可能如下所示: class MyClass{
我正在使用 powershell 命令来执行脚本和 cmdlet。因此,在执行 cmdlet 时,我使用了 powershell.invoke,而在执行脚本时,我使用了 pipeline.invoke
有人能解释一下 Invoke-Expression $test 之间的区别吗?和 Invoke-Expression -Command $test ? 变量测试是: $test = "notepad
我有四个类,即 MapperOne、ReducerOne、MapperTwo、ReducerTwo。我想要其中的一个链。 MapperOne-->ReducerOne-->输出文件生成,输入到Mapp
我正在阅读 Java ForkJoin 框架。不直接在 ForkJoinTask 的实现上调用 invoke()(例如 RecursiveTask),而是实例化 ForkJoinPool 有什么额外的
我在调用 Invoke-SqlCmd 时遇到问题,因为它包含第二个 Invoke-SqlCmd 调用: function Get-Foo { $query=` @" WITH data AS (
有人知道如何解决这个问题吗?我创建了一个客户端来使用网络服务。客户端代码为: package cliente; import java.util.List; import handler.Header
我希望使用 P/Invoke 来允许我的 C# 程序集与 native C 库互操作;这需要是跨平台的(即 Mono),因此不能使用混合模式程序集。我想知道使用不安全的 P/invoke 调用并在不安
一般来说,我对使用 Invoke-RestMethod/Invoke-WebRequest 比较陌生 - 我认为这是以下问题的重要背景。 我正在调用如下电话: $Headers = @{ "A
在 Jenkins 的一个自由风格项目(不是说 Maven2/3 项目)中,我有两个可能的构建步骤: 调用 Maven 3 调用顶级 Maven 目标 在不同的安装中,我有不同的组合(有些两者都有,有
这是完整的错误: e: C:\Users\HP\AndroidStudioProjects\MoneyManager\app\src\main\java\com\cruxrepublic\moneym
我正在编写 jQuery 插件并将它们与 AJAX 集成。我正在减少脂肪并专注于基础知识: (function($) { function MyPlugin(el, options) {
有人可以建议我如何处理这条消息吗? CA1060 Move P/Invokes to NativeMethods class Because it is a P/Invoke method, 'UCo
在java中我们可以“用类名调用一个静态方法”也可以“用一个对象调用一个静态方法”java中“用类名调用静态方法”和“用对象调用静态方法”有什么区别? 最佳答案 没有区别,但建议以静态方式调用 sta
尝试从对话框中的 EditText 获取 Edit Text 的值,但一次又一次地出现此错误 Attempt to invoke virtual method 'android.text.Editab
我正在开发一款扑翼应用程序。在出现此错误之前,读取和写入FireStore数据库没有任何问题,但随后突然出现错误(如下所示),并阻止我读取或写入数据库。我一直在寻找答案,但不幸的是,我找不到任何可以解
我是一名优秀的程序员,十分优秀!