Delphi:如何使用 DynArraySetLength 设置 RTTI 访问的动态数组的长度?

2023-11-29

我想设置动态数组的长度,如建议的那样这个帖子。我有两个类 TMyClass 和相关的 TChildClass 定义为

TChildClass = class
private
  FField1:  string;
  FField2:  string;
end;

TMyClass = class
private
  FField1:  TChildClass;
  FField2:  Array of TChildClass;
end;

数组增广实现为

var
  RContext:     TRttiContext;
  RType:        TRttiType;
  Val:          TValue;      // Contains the TMyClass instance
  RField:       TRttiField;  // A field in the TMyClass instance
  RElementType: TRttiType;   // The kind of elements in the dyn array
  DynArr:       TRttiDynamicArrayType;
  Value:        TValue;  // Holding an instance as referenced by an array element
  ArrPointer:   Pointer;
  ArrValue:     TValue;
  ArrLength:    LongInt;
  i:            integer;
begin
  RContext := TRTTIContext.Create;
  try
    RType := RContext.GetType(TMyClass.ClassInfo);
    Val := RType.GetMethod('Create').Invoke(RType.AsInstance.MetaclassType, []);
    RField := RType.GetField('FField2');
    if (RField.FieldType is TRttiDynamicArrayType) then begin 
      DynArr := (RField.FieldType as TRttiDynamicArrayType);
      RElementType := DynArr.ElementType;
      // Set the new length of the array
      ArrValue := RField.GetValue(Val.AsObject);
      ArrLength := 3;   // Three seems like a nice number
      ArrPointer := ArrValue.GetReferenceToRawData;
      DynArraySetLength(ArrPointer, ArrValue.TypeInfo, 1, @ArrLength);
      { TODO : Fix 'Index out of bounds' }
      WriteLn(ArrValue.IsArray, ' ', ArrValue.GetArrayLength);
      if RElementType.IsInstance then begin
        for i := 0 to ArrLength - 1 do begin
          Value := RElementType.GetMethod('Create').Invoke(RElementType.AsInstance.MetaclassType, []);
          ArrValue.SetArrayElement(i, Value);
          // This is just a test, so let's clean up immediatly
          Value.Free;
        end;
      end;
    end;
    ReadLn;
    Val.AsObject.Free;
  finally
    RContext.Free;
  end;
end.

作为 D2010 RTTI 的新手,我怀疑该错误可能取决于从类实例获取 ArrValue,但随后的WriteLn打印“TRUE”,所以我排除了这一点。然而令人失望的是,同样WriteLn报告 ArrValue 的大小为 0,这是由“索引越界”确认的——尝试设置数组中的任何元素时出现的异常(通过ArrValue.SetArrayElement(i, Value);)。有谁知道我在这里做错了什么? (或者也许有更好的方法来做到这一点?)TIA!


动态数组使用起来有点棘手。它们是引用计数的,DynArraySetLength 中的以下注释应该可以阐明该问题:

// 如果堆对象不是共享的(引用计数 = 1),只需调整它的大小。否则,我们会复制一份

您的对象持有对其的一个引用,TValue 也是如此。此外,GetReferenceToRawData 还为您提供了指向数组的指针。你需要说PPointer(GetReferenceToRawData)^获取要传递给 DynArraySetLength 的实际数组。

一旦你得到了它,你可以调整它的大小,但你留下了一个副本。然后你必须将其设置回原始数组。

TValue.Make(@ArrPointer, dynArr.Handle, ArrValue);
RField.SetValue(val.AsObject, arrValue);

总而言之,仅使用列表而不是数组可能要简单得多。使用 D2010,您可以使用 Generics.Collections,这意味着您可以制作TList<TChildClass> or TObjectList<TChildClass>并具有列表类的所有优点,而又不失去类型安全性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi:如何使用 DynArraySetLength 设置 RTTI 访问的动态数组的长度? 的相关文章

  • 如何对 PHP 数组中的值进行排序/过滤?

    我需要 foreach 这个数组的值 My CODE 该代码的结果 Array 0 gt Array 0 gt Age Name 1 gt 22 Yrs Value 2 gt Ethnicity Name 3 gt Caucasian Va
  • Javascript 无法正确排序 DECIMAL 数字

    我有一些代码可以按字母顺序对名称进行排序 我遇到的问题是它处理小数的方式 它对名称进行排序 如下所示 我宁愿它按数字递增 DOG 1 0510 DOG 1 1031 DOG 11 1792 DOG 12 0920 DOG 12 1170 D
  • 为什么byteArray的长度是22而不是20?

    我们尝试从字符串转换为Byte 使用以下 Java 代码 String source 0123456789 byte byteArray source getBytes UTF 16 我们得到一个长度为 22 字节的字节数组 我们不确定这个
  • 奇怪的java字符串数组空指针异常[重复]

    这个问题在这里已经有答案了 这个问题是在实践测试中出现的 创建一个新的字符串数组 将其初始化为空 然后初始化第一个元素并打印它 为什么会出现空指针异常呢 为什么它不打印 一 这与字符串不变性有关吗 public static void ma
  • 向用户显示多条验证消息

    在 MS Access 中 如何将从 SELECT 语句检索到的行存储在数组中 并在一个消息框中显示多行 Dim rSEL rSUM rDes As DAO Recordset Dim vItem id vQnty vSum As Inte
  • C# 如何在运行时动态生成实现不同接口的对象?

    我正在研究如何解决问题 但我什至不确定这在 C 和 NET 3 5 中是否可行 假设我的接口数量有限 每个接口都描述一组特定的 不相关的方法 现在我有许多现实世界的设备 每个设备都可以仅实现这些接口的一个子集 在与这些设备建立通信期间 他们
  • 在php中对带有特殊字符的多维数组进行排序

    我有一个多维数组 我按字母顺序排序 但问题是 带有丹麦语特殊字符 它们应该按该顺序排序 但不会按该顺序返回 这是我的数组 部分已删除 Array 0 gt Array Name gt John 1 gt Array Name gt Pate
  • 是否保证 sizeof(T[N]) == N * sizeof(T) ?

    我一直假设 N 个元素类型的数组的大小T 由返回sizeof保证正好是N次sizeof T The 对这个问题的评论 https stackoverflow com questions 46457449 is it always the c
  • 如何获取属于某个进程的打开句柄的计数?

    您可以使用该程序流程浏览器 http technet microsoft com en us sysinternals bb896653查看正在运行的应用程序有多少个句柄 有没有办法用Delphi代码来获取这个数字 我有兴趣跟踪应用程序本身
  • 对数字和字母元素的数组进行排序(自然排序)

    假设我有一个数组 var arr 1 5 ahsldk 10 55 3 2 7 8 1 2 75 abc huds 我尝试对其进行排序 我得到了类似的东西 1 1 10 2 2 3 5 55 7 75 8 abc ahsldk huds 注
  • 编译器消息“警告:格式‘%s’需要类型‘char *’,但参数 2 具有类型‘char (*)’”

    我正在尝试运行一个简单的 C 程序 但收到此错误 警告 格式 s 需要类型 char 但参数 2 的类型为 char 20 我在跑步Mac OS X v10 8 https en wikipedia org wiki OS X Mounta
  • 根据数组计数填充复选框

    我是新来的php我已经使用了它的开发php array 我想填充checkboxes根据数组计数 为了做到这一点 我尝试了以下方式 它对我不起作用 有什么方法可以做到这一点 在我的例子中 数组计数 5 所以我相应地需要 5 个复选框
  • 在Python 3中将二进制字符串转换为字节数组

    尽管有很多相关的问题 但我找不到任何符合我的问题的问题 我想更改二进制字符串 例如 0110100001101001 转换成字节数组 同一个例子 b hi 我试过这个 bytes int i for i in 011010000110100
  • Java中整数数组的排列算法

    我有一个工作示例来生成字符串中的所有字符排列 如下所示 static ArrayList
  • 在 Numpy 中切片后确定结果数组的形状

    我很难理解在 numpy 中切片后如何确定结果数组的形状 例如 我使用以下简单代码 import numpy as np array np arange 27 reshape 3 3 3 slice1 array 1 2 1 slice2
  • 如何按值删除数组中的多个项目?

    我正在尝试做一个removeAll 函数 它将删除具有该特定值 而不是索引 的数组的所有元素 当我们对循环进行任何更改时 棘手的部分就出现了 索引往往会移动 使其很难像我们想要的那样工作 并且每次更改时都重新启动循环 这在大数组上效率非常低
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 从java中的字符串数组中删除空值

    java中如何从字符串数组中删除空值 String firstArray test1 test2 test4 我需要像这样没有 null 空 值的 firstArray String firstArray test1 test2 test4
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 将一维数组转换为二维数组[重复]

    这个问题在这里已经有答案了 我正在开发一个程序 我必须将文本文件中的值读入一维数组 我已经成功获取该一维数组中的数字 m1 1 2 3 4 5 6 7 8 9 但我希望数组是 m1 1 2 3 4 5 6 7 8 9 您可以使用此代码 co

随机推荐

  • Android:如何保存用户填写的表单的html文件

    I was able to download this form to my sdcard from a given URL 我的应用程序可以通过 Android Web 视图访问此表单 我的问题是 用户在表单中填写数据后如何将其保存到文本
  • 无法从 MAC OSX 上的后台 java 应用程序复制到剪贴板

    我们有 2 个 Java 应用程序在 MAC 上运行 一个后台应用程序将文本或图像发送到剪贴板 然后另一个应用程序抓取该数据并将其粘贴到其应用程序中 当应用程序在剪贴板上复制某些内容时 我们会遇到这个问题 后台应用程序将无法更新剪贴板 直到
  • 杰克逊+建造者模式?

    我希望杰克逊使用以下构造函数反序列化一个类 public Clinic String name Address address 反序列化第一个参数很容易 问题是 Address 定义为 public class Address privat
  • 如何查看linux的socket缓冲区大小

    Linux 的默认套接字缓冲区大小是多少 有什么命令可以看到吗 如果您想在终端中查看缓冲区大小 您可以查看 proc sys net ipv4 tcp rmem 供阅读 proc sys net ipv4 tcp wmem 用于写入 它们包
  • 为线程配置 log4j2

    有一个类叫做Test 它延伸自Thread 如何配置 log4j2 以便为每个测试线程创建我自己的日志文件 我正在尝试这样做 public class Test extends Thread private String name priv
  • 在 COCOS2D 中移动的触摸上绘制线条

    我正在使用 iPhone 开发一款游戏COCOS2D 其中 当用户将手指从一个点拖动到另一个点时 我需要画一条线 据我所知 我需要这样做Touches Moved method从哪里我可以获得积分 但我不知道该怎么做 有人能帮我解决这个问题
  • 如何在Xamarin中使用研究套件框架

    我正在使用 ResearchKit 制作一个健康应用程序 我想在 Xamarin 中执行此操作 因为我已经有很多可以在 Xamarin 中使用的共享代码 然而 研究套件尚未集成到 Xamarin 中 我正在考虑将框架绑定到我在 Xamari
  • 使用 EWS 托管 API 2.0 为现有约会绑定自定义扩展属性

    我想使用自定义扩展属性进行唯一的预约以放入数据库 我使用 FindAppointments 查找所有约会 var appointments service FindAppointments WellKnownFolderName Calen
  • 在 PHP 中使用正则表达式找出子域

    抱歉 如果这个挑战太小 不适合作为堆栈溢出问题 但我对正则表达式有点陌生 我的问题是 对于下面的所有示例返回字符串 token 的正则表达式是什么 token domain com token domain com token domain
  • 如何删除多页文档中的空白页?

    编辑 添加了一个答案 因为编辑太长 参见答案2 继以前关于文档合并的帖子我最终得到了一个工作脚本 感谢 Henrique 但我仍然有一个小问题 最终的 合并 文档有时包含我想删除的空白页面 取决于其他文档内容 我找不到简单的方法来做到这一点
  • 如何使用 ggrepel (或其他方式)在 ggalluvial 中对齐和标记地层

    我有一些使用生成的冲积地块ggalluvial in R 下面的代码示例产生的结果接近我想要实现的目标 例如 library ggalluvial par mar c 1 1 1 1 12 cex 0 6 xpd NA generate s
  • VBScript - 从标准输出捕获输出

    我知道这已经在另一个问题中得到了回答 但我根本不明白它是如何完成的 我试图将命令行程序 Aria2 下载器 的输出获取到 HTA 脚本中 以便可以对其进行解析 并且可以获取下载百分比 文件大小等并将其动态更新到 DIV 中 这是我已经调整并
  • Windows服务中的定时器队列

    对于 Windows 服务 我需要一个计时器来定期执行特定任务 当然 有许多选项似乎优于计时器 多线程 直接从服务的主线程调用方法 但在这种特定情况下它们都有其缺点 然而 由于显而易见的原因 如果没有 GUI 的消息队列 SetTimer
  • ReplicaSet 失败并显示无效:spec.template.metadata.labels

    为了我的学习目的 我正在尝试对replicaSet进行一些研究 我能够使用 matchLabels 成功创建副本集 为了测试 matchExpression 选择器 我首先创建了一个 pod 然后创建了一个新的副本集 以测试副本集是否能够检
  • UIWebview 缩放 PDF 和大 .图像缩放 默认 IOS

    我在用UIWebView加载具有缩放功能的 PDF 和图像 为此我检查了webView scalesPageToFit属性真实且工作正常 但我的问题是 当我加载大图像 2496 3507 时 它默认显示缩放 我不希望尺寸适合 为了克服这个问
  • 链接器命令失败,退出代码为 1;架构armv7s的未定义符号。

    这是我第一次尝试将二进制文件 iOS 应用程序的新版本 而不是全新的应用程序 上传到 iTunes 商店 当我尝试创建存档时 我收到三个Apple Mach o linker errors 在问题导航器中显示为红色 这是显示的内容 ld w
  • jQuery Masonry 与 jQuery UI Sortable 冲突

    使用 Masonry 时 jQuery UI Sortable 不起作用 知道如何避免这种冲突吗 任何帮助 将不胜感激 我想我也有类似的问题 我通过简单地调用代码中用于设置可排序元素的砌体来修复它 可能有更好的方法 我不确定 functio
  • 垂直对齐浮动 DIV

    我正在创建的网站的一部分如下 div div div div
  • asp:按钮点击事件没有被触发

    我正在 asp 表中动态添加行 在表的每一行中 我还包括一个具有 SelectProduct Click 事件的按钮 问题是 即使我注册了单击事件 该事件也没有被触发 按钮是这样添加的 btnSelect new Button btnSel
  • Delphi:如何使用 DynArraySetLength 设置 RTTI 访问的动态数组的长度?

    我想设置动态数组的长度 如建议的那样这个帖子 我有两个类 TMyClass 和相关的 TChildClass 定义为 TChildClass class private FField1 string FField2 string end T