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 - 按名称调用记录方法 的相关文章

  • 如何添加资源并使用它们

    在我的应用程序中 我想添加 2 个图像作为资源 我想使用这些图像 当我在应用程序中单击 是 按钮时 第一张图像将被设置为壁纸 当我在应用程序中单击 否 按钮时 第二张图像将被设置为桌面壁纸 提前致谢 regards 最简单的方法是创建一个文
  • Delphi (Indy) TIdTCPClient 在线程中

    在互联网上 我看到通常将 TIdTCPClient 放置在自定义 TThread 后代中 为什么要这样做 有时我也在这样的线程中看到服务器 为什么 干杯 阿德里安 Indy 使用阻塞 I O 最好在线程中处理 这是 Indy 整体设计的核心
  • 如何以编程方式安排任务

    如何使用 delphi 7 像 Google updater 一样安排任务 我没有使用注册表 因为它被卡巴斯基防病毒软件检测为误报 我在注册表中作为启动项添加的任何内容都会被检测为特洛伊木马 因此我决定使用任务计划 下面的代码展示了如何删除
  • VCL.位图到 FMX.位图

    我在网上找到了这段代码 但 FMX Bitmap 没有扫描线 是否可以以某种方式将 VCL TBitmap 复制或绘制到 FMX Bitmap IFDEF MSWINDOWS type TBitmap FMX Types TBitmap T
  • 如何在 Vista 上安装 Delphi 7

    我多次尝试在 Vista 上安装 Delphi 7 但 Vista 告诉我此应用程序 Delphi 7 存在已知问题 从而阻止了我这样做 我公司的其他几个人在 Vista 上安装 D7 时遇到了问题 由此得出的结论是 我们的 D7 应用程序
  • 我可以让我的 Delphi 应用程序在特定时间(例如上午 12:00)启动,而不运行应用程序吗?

    我看到一个已安装的应用程序 它从供应商的网站提供一些 XML 数据并将其显示在主窗体窗口中 我想这很简单 但我注意到 即使我关闭系统托盘中的应用程序 明天早上 上午 12 00 正好 它也会再次弹出 这太酷了 我不确定它是用 Delphi
  • Delphi - 自XE8以来如何正确注册图形类?

    我正在编写一个 Delphi 包 它提供了一个新的自定义 TGraphic 对象 允许读取 VCL 组件 如 TImage 中的新图像格式 我最初使用 RAD Studio XE7 开发了这个包 并且运行良好 然而 我最近迁移到了较新的 R
  • 运行delphi客户端自动化程序后excel.exe保持加载状态的原因是什么?

    我编写了一个 Delphi 程序 该程序从单个 XLS 文件的多个不同电子表格中提取数据并将其合并到文本文件中以供以后处理 这是德尔福7console程序 最相关的代码片段的摘录将向您表明 显然 我的程序表现得相当好 或者至少达到了它需要的
  • 开源 Delphi 包可使用哪些项目选项?

    我写了一些 Delphi 代码 想在 GitHub 上分享 所有代码都根据需要包含在运行时和设计时包中 每个项目有许多项目选项需要设置 输出目录 搜索路径 编译选项等 我设法找到了一些适合我的情况的默认选项 但阅读此处的其他问答很明显有多个
  • 不断断点?如何去除它们?

    我下载了一个用Delphi 2009制作的项目 这也是我使用的 但是有一个断点我无法删除 如果我尝试删除它 它会在程序执行后再次执行 我在其他调试器中遇到了这样的事情 称为硬件断点 但这并不重要 如何删除断点 EDIT Article ht
  • Word 2010 自动化:“转到书签”

    我有一个用 Delphi 7 编写的程序 它打开一个基于模板的新 Word 文档 文档打开后 系统会自动跳转到书签 在模板中预定义 并在其中添加一些文本 以下代码在 Word 2003 中工作正常 但会导致invalid variant o
  • 具有 csOwnerDrawFixed 样式的组合框如何表现得像 csDropDown 样式?

    我正在使用一个组合框 http docwiki embarcadero com Libraries en Vcl StdCtrls TComboBoxstyle 属性设置为的组件csOwnerDrawFixed 我实现了绘图项一切工作正常
  • 在 Delphi 中使用 XML(将特定数据返回到变量)

    过去几天我一直在尝试使用 Delphi 2010 和 MSXML 我是一个极端的新手 需要一点指导 var MemoryStream TMemoryStream XMLPath String sName String XMLDoc vari
  • 石和磅的格式正确吗?

    我有一个图表 用于显示重量 以英石和磅 lbs 为单位 该图表由记录中的数据填充 对于权重 数据类型为 Double 记录数据是在运行时编辑的 我需要知道一种正确格式化输入数据的方法 为了更好地理解 首先看一下这些示例值 它们表示为石和磅
  • TObjectList.Contains 导致 Delphi 2009 中的访问冲突

    在 Delphi 2009 中 到目前为止 我在泛型方面没有遇到大问题 使用 Generics Collections 列表 没有特殊的泛型功能 现在我发现这段代码会在访问的行中导致AVMyList Contains 如果我声明 TMyLi
  • 如何从 VCL.Graphics 获取所有已注册的文件格式...但 64 位

    在我的 32 位应用程序中 我使用FindRegisteredPictureFileFormats 单元由 Cosmin Prund 提供 https stackoverflow com a 14677532 505088 gt 如何从图形
  • 所见即所得与 Unicode

    我在 Delphi 中编写了一个 Windows 程序 该程序使用 GetCharWidth 和 Em Square 将文本非常精确地放置并换行到屏幕和打印机 这对于 ANSI 文本效果很好 您只需要检索和计算 255 个字符的宽度 但当您
  • 将 [字节数组] 分配给没有 Unicode 转换的 Variant

    考虑以下代码片段 在 Delphi XE2 中 function PrepData StrVal string Base64Val AnsiString OleVariant begin Result VarArrayCreate 0 1
  • 可以在滚动条上绘画吗?

    是否可以在 TMemo TListbox 等标准控件的滚动条上进行绘制 我所需要的只是在滚动条上绘制一些基本形状 并且我试图避免从 stratch 实现整个滚动内容 有什么指点吗 蒂亚 确实有可能 你可能想看一下WM NCPAINT消息 这
  • TThread.resume 在 Delphi-2010 中已弃用,应该在什么地方使用?

    在我的多线程应用程序中 I use TThread 挂起 and TThread resume 自从将我的应用程序移至 Delphi 2010 后 我收到以下警告消息 DCC 警告 xxx pas 277 W1000 符号 Resume 已

随机推荐

  • 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