Delphi - 按名称调用记录方法

2024-02-08

我为我的应用程序编写了一种脚本语言,我的目标是能够在脚本中发布来自 delphi 的任何类型。我使用 rtti 来自动执行此任务。对于任何实例类型(例如类),我使用以下代码从脚本查找并调用方法。

var  Info : TRttiType;  
     Meth : TRttiMethod;  
     Param : TArray<TValue>;  
     Result : TValue;  
     AnyClass : TClass;   
begin  
  ...  
  Info := RttiContext.GetType(AnyClass);  
  Meth := Info.GetMethod('AMethod');  
  Setlength(Param, 1);  
  Param[0] := TValue.From<Integer>(11);  
  Result := Meth.Invoke(ClassInstance, Param);  
  ...  
end;  

但对于记录,此代码不起作用,因为 TRttiMethod 类型不提供记录类型的 Invoke() 方法。我可以通过 Info.GetMethod('AMethod') 从记录类型访问方法信息。
例如我有这样的记录:

TRecordType = record  
  Field1, Field2 : single;  
  procedure Calc(Value : integer);   
end;  

那么,如果我有方法名称或方法地址,有人知道如何从记录中调用方法吗?


在探索了上面评论中发布的 delphi 文档中的链接之后,我仔细研究了 System.Rtti 中的 delphi 类型 TRttiRecordMethod。它提供了 DispatchInvoke() 方法,并且该方法需要一个指针。 所以下面的代码有效:

TRecordType = record   
  Field1, Field2 : single;   
  procedure Calc(Value : integer);    
end; 


  Meth : TRttiMethod; 
  Para : TRttiParameter; 
  Param : TArray<TValue>; 
  ARec : TRecordType; 
begin 
  Info := RttiContext.GetType(TypeInfo(TRecordType)); 
  Meth := Info.GetMethod('Calc'); 
  Setlength(Param, 1); 
  Param[0] := TValue.From<Integer>(12); 
  Meth.Invoke(TValue.From<Pointer>(@ARec), Param); 
end; 

如果您想调用静态方法或重载运算符,则代码不起作用。 Delphi内部总是将self指针添加到参数列表中,但这会导致访问冲突。因此,请改用以下代码:

  Meth : TRttiMethod; 
  Para : TRttiParameter; 
  Param : TArray<TValue>; 
  ARec : TRecordType; 
begin 
  Info := RttiContext.GetType(TypeInfo(TRecordType)); 
  Meth := Info.GetMethod('&op_Addition'); 
  ... 
  Meth.Invoke(TValue.From<Pointer>(@ARec), Param); 
  Result := System.Rtti.Invoke(Meth.CodeAddress, Param, Meth.CallingConvention, Meth.ReturnType.Handle, Meth.IsStatic); 
end;    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi - 按名称调用记录方法 的相关文章

  • Delphi - 列表索引越界(4)

    我知道这个问题已经被提出了一百万次 但是 我无法理解为什么这段代码会抛出错误 我已经找到了导致错误的罪魁祸首 FOR 循环 但是 我没有看到它有任何问题 我收到错误 列表索引超出范围 4 function TNetwork FeedForw
  • SATA 驱动器的硬盘 ID

    我正在为我的软件使用硬盘 ID 来检查真实用户是否正在使用该软件 对于 IDE 类型硬盘 我使用过程 GetIdeSerialNumber 获取 id 但如果是 SATA 驱动器 则 ID 为空 然后 对于 SATA 驱动器 我使用卷 ID
  • Delphi:MDI应用程序中的最大化子窗体

    如何最大化仅适合客户区而不适合整个父窗口的子窗口 我不希望子窗口在父窗口的主菜单或其他控件下消失 我有这个代码 procedure WMSIZE var Msg TMessage message WM SIZE procedure TFor
  • 如何将参数传递给 OLE 自动化对象(例如 MS Word)

    这主要是一个Delphi语法相关的问题 调用 OLE 对象的方法时 我需要将参数设置为 True 我需要在Word Automation中设置 这是来自词参考 http support microsoft com kb 285885 en
  • 如何发送/接收 JSON?

    我知道这是一个愚蠢的问题 但我通常不进行 Web 编程 并且被要求发送一些 JSON 数据并接收一些回报 我用谷歌搜索 很清楚如何编码和解码 JSON 数据 但我对此很陌生 我不知道如何与给定的 URL 进行通信并说 这里有一些数据 请发回
  • ClientDataset 索引更改时不计算 TAggregateField

    我正在使用连接到 DBGrid 的 TClientDataset 和几个聚合字段 用于计算其他几个浮点字段的总和 所有字段均已在设计时创建 一切都按预期工作 直到 ClientDataset 的 IndexName 使用自定义索引更改 以便
  • Move() 从动态字符串数组中插入/删除项目

    使用 System Move 从字符串数组中插入 删除项目并不像从其他简单数据类型数组中插入 删除项目那么容易 问题是 字符串在 Delphi 中是引用计数的 在引用计数数据类型上使用 Move 需要对内部编译器行为有更深入的了解 这里有人
  • 桌面 Delphi 应用程序是否可以通过 Windows 8 认证(使用 Windows 应用程序认证套件)?

    显然 Delphi 任何版本 不支持安全异常处理程序 https forums embarcadero com thread jspa messageID 473469 Visual Studio 中的 SAFESEH 开关 在 Windo
  • 可以在delphi数据集中创建一个假数据字段吗?

    我想在 DataSet 不是 ClientDataSet 中创建一个 假 数据字段 该字段不应存储在数据库中 它不是计算字段 应允许用户输入输入数据 该字段具有业务逻辑含义 因此用户更新其值后应该更新其他字段 使用 OnFieldChang
  • 作为属性的类引用

    谷歌对于这类搜索毫无用处 因为你会得到数亿个结果 其中没有一个与特定问题相关 问题很简单 Delphi 中是否可以有类引用属性 如果是这样 怎么办 这是我尝试过的 type TMyObject class end TMyObjectClas
  • Firemonkey - 更新视觉组件

    我们从版本 1 开始就使用 Firemonkey 但仍然发现更新当前在屏幕上可见的组件很困难 在 Firemonkey 中请求重画的 方式 有很多 也许太多了 应用样式 ApplyStyle 事件 主要是当它在屏幕上可见时 请求 repai
  • 如何仅在某些列中设置带有复选框的 TListView?

    我正在使用 Delphi 2010 并且我试图允许用户在 TListView 中的每行 2 个选项之间进行选择 使用 TListView 我可以将样式设置为 vsReport 并启用复选框 但这只会让我每行有 1 个复选框 我需要的是每行
  • DELPHI win32 的 ORM [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有谁知道 Delphi Win32 的 ORM 或类似的东西吗 Marco Cantu 是 Insta
  • TRESTRequest:是否可以在 POST 请求中使用自定义媒体类型?

    例如 我们有一个 API 需要我们自己的供应商特定内容类型application vnd xxxx custom custom data json但查看 REST Client 的源代码 它似乎总是默认为 REST Types 中的 Con
  • 当通过音频采样的数据数量超过 AudioRecord 构造函数中设置的“bufferSizeInBytes”时会发生什么?

    public AudioRecord int audioSource int sampleRateInHz int channelConfig int audioFormat int bufferSizeInBytes 这是公共构造函数Au
  • Delphi 2010:如何将 UTF8 编码的 PAnsiChar 转换为 UnicodeString?

    情况 我有一个外部 DLL 它使用 UTF 8 作为其内部字符串格式 接口函数都使用 PAnsiChar 来传递字符串 我的应用程序的其余部分使用 Delphi 的本机string类型 由于我正在使用 Delphi 2010 这将映射到Un
  • 如何使用 jQuery 和“长轮询”通过 Indy HTTP 服务器动态更新 HTML 页面?

    我读过这篇文章使用 JavaScript 和 jQuery 的简单长轮询示例 http techoctave com c7 posts 60 simple long polling example with javascript and j
  • Indy FTP 传输类型

    我正在使用 IdFTP Indy 10 组件从远程位置下载一些文件 zip 和 txt 在获取每个文件之前 我将 TransferType 设置为二进制 IdFTP TransferType ftBinary IdFTP Get ASour
  • Winform 没有.NET 框架?

    我必须创建一些表单并将其作为直接 EXE 提供 而不是安装程序 它安装 NET 框架 最终用户对此不满意 他们想要可以直接打开和工作的东西 我知道它可以作为网络完成 但我正在寻找 winforms 吗 请建议哪种工具 技术可以处理这个问题
  • 如何允许表单接受文件删除而不处理 Windows 消息?

    在 Delphi XE 中 我可以允许我的表单接受文件 拖放 但不必处理裸窗口消息吗 您不需要处理消息来实现这一点 你只需要实施IDropTarget并打电话RegisterDragDrop RevokeDragDrop 这真的非常非常简单

随机推荐

  • Virtualbox限制网络带宽[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我使用的是虚拟机VirtualBox 现在 我需要限制带宽 我有 2 个虚拟机正在运行 一种只是为了好玩 一是用于重要的数据库访问 如果
  • 测试它是 JSONObject 还是 JSONArray

    我有一个 json 流 可以是这样的 intervention id 3 subject dddd details dddd beginDate 2012 03 08T00 00 00 01 00 endDate 2012 03 18T00
  • 如何在pygame中从一种颜色淡入另一种颜色?

    我如何在 pygame 中从一种颜色淡入另一种颜色 我想慢慢地改变一个圆圈的颜色 从绿色到蓝色到紫色到粉色到红色到橙色到黄色到绿色 我该怎么做呢 目前 我正在使用 def colour switcher 0 0x2FD596 1 0x2FC
  • 自动附加支持行为未完全成功

    我有一个包含多个 C 项目的 Visual Studio 2010 解决方案 安装并启用了 Resharper 5 1 所有这些项目都以 NET Framework 4 为目标 该解决方案几个月来一直运行良好 但今天早上加载解决方案时我收到
  • ireport 4.0.1 中报表的动态宽度

    我在ireport4 0 1中设计了一个交叉表报表 由于交叉表 我不知道报告的宽度 是否有任何选项可以根据其包含的数据设置宽度 好吧 我的答案可能不是 jaspersoft 人员推荐的答案 但我要做的是在运行时计算所需的宽度 然后将值放入
  • 从 DataTemplate 上的按钮获取 ListBox 行对象

    我有一个ListBox with a DataTemplate 该模板有一个Button在上面 当 的时候Button单击我想对每行的对象执行一些逻辑 在本例中是一个名为WorkItemTypeMappings In theOnClick我
  • 是否可以检查您是否正在使用 Microsoft C 编译器构建 64 位版本?

    是否有为 64 位构建定义的简单预处理器宏 我想 WIN64可能是这样 但即使当我构建 32 位目标时 包含在 ifdef WIN64 endif被编译进去 这会引起问题 今天是星期五 我无法正常思考 但我确信我忽略了一些非常简单的事情 甚
  • 如何向rails4添加自定义动词(http请求方法)

    我想向 Rails 4 添加自定义 http VERB 这是我的路线 rb ring session gt calls ringing 我还将这段代码放入初始化程序中 w ring busy each do method ActionDis
  • CMake 排除子目录中的测试

    我有一个包含 libevent 库的 C 项目 项目结构 CMakeLists txt Makefile src my lib cpp test my lib test cpp lib libevent CMakeLists txt 当我构
  • 如何将线程异常传播回应用程序异常处理程序

    http msdn microsoft com en us magazine gg598924 aspx http msdn microsoft com en us magazine gg598924 aspx 为什么 WPF Dispat
  • 何时使用构建工具?

    一个初学者问题 请耐心等待 我只是想知道在什么情况下应该使用像 nant 或 msbuild 这样的构建工具 我正在开发一个中型应用程序 net 3 0 每个开发人员都在做他的工作并在他的机器上进行构建 检查他的代码更改到存储库中 全部完成
  • 对象未使用 JPA/JTA/JBOSS/CDI 持久化

    请帮助我理解为什么对象没有通过以下代码持久化 它抛出javax persistence TransactionRequiredException JBAS011469 需要事务来执行此操作 使用事务或扩展持久性上下文 public clas
  • 设置 3 个元素的高度,取最大值,跨多行

    我有一个 div 布局 全部向左浮动 列数为 3 这些层内部是长度不同的文本 因此层的高度不同 因此无法正确对齐 而且看起来也不太好 因为边框不身高匹配 我可以为所有 div 设置固定高度 但这会在某些行上留下巨大的空白 因此我编写了一些
  • Laravel:Redis 无法建立连接:[tcp://127.0.0.1:6379]

    我已经用 laravel 安装了 redis 添加了 predis predis 1 0 然后为了测试我添加了以下代码 public function showRedis id 1 user Redis get user profile i
  • Rails 4 和 Devise:Devise 不保存新信息(名字、姓氏、个人资料名称)

    我正在使用 Rails 4 和 Devise 我正在尝试在我的应用程序上发布的状态中显示用户的名字 我已经正确完成了我能想到的所有事情 添加用户模型后迁移数据库 并且数据库仍然没有保存我标题中列出的三个新字段 Devise 保存它附带的内容
  • kotlin,如何将 HashMap 放入 Parcelable 中

    在实现 Parcelable 的类中 它有一个 HashMap 成员 看到 Parcelable 有public final void readMap Map outVal ClassLoader loader 但找不到使用它的示例 如果通
  • 如何在不破坏皮肤的情况下向 MediaWiki 站点添加水平顶部菜单栏?

    我希望我的 MediaWiki 网站 除了侧边栏之外 或者代替侧边栏 在网站顶部有一个链接栏 在每个页面上都可见 要求 为了尽量减少以后的维护负担 我的要求是 无需修改核心 扩展或皮肤代码 我不想维护项目分支 理想情况下 特权用户应该能够通
  • WPF 可见性绑定到具有多个变量的布尔表达式

    我有两个布尔值 我想根据它们的值显示图像 如下所示
  • Java:将二进制字符串转换为十六进制字符串[重复]

    这个问题在这里已经有答案了 我需要将二进制字符串转换为十六进制字符串 但我有一个问题 我通过以下方法将二进制字符串转换为十六进制字符串 public static String binaryToHex String bin return L
  • Delphi - 按名称调用记录方法

    我为我的应用程序编写了一种脚本语言 我的目标是能够在脚本中发布来自 delphi 的任何类型 我使用 rtti 来自动执行此任务 对于任何实例类型 例如类 我使用以下代码从脚本查找并调用方法 var Info TRttiType Meth