如何使用delphi 2010 rtti设置数组长度
发布时间:2020-12-15 09:23:52 所属栏目:大数据 来源:网络整理
导读:如何在运行时设置数组长度? setLength(t.GetProperty( ‘Propertys’),3); ???? unit Unit3; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls; type TSubProperty = Class private Fitem2: Integer;
如何在运行时设置数组长度?
setLength(t.GetProperty( ‘Propertys’),3); ???? unit Unit3; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls; type TSubProperty = Class private Fitem2: Integer; Fitem1: String; procedure Setitem1(const Value: String); procedure Setitem2(const Value: Integer); published property item1:String read Fitem1 write Setitem1; property item2:Integer read Fitem2 write Setitem2; End; TArraySubPropertys=array of TSubProperty; TmyObject = Class private FPropertys: TArraySubPropertys; procedure SetPropertys(const Value: TArraySubPropertys); published property Propertys:TArraySubPropertys read FPropertys write SetPropertys; End; TForm3 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.Button1Click(Sender: TObject); var myObject:TmyObject; ctx : TRttiContext; t : TRttiType; obj:TObject; begin myObject :=TmyObject.Create; ctx := TRttiContext.Create; t := ctx.GetType(myObject.ClassType); // setLength(t.GetProperty('Propertys'),3); ???????????????????????????????????? obj:= (t.GetProperty('Propertys').PropertyType as TRttiDynamicArrayType).ElementType.AsInstance.MetaclassType.Create; //showmessage(obj.toStirng); --> TSubProperty t.GetProperty('Propertys').getValue(myObject).setArrayElement(0,obj); obj:= (t.GetProperty('Propertys').PropertyType as TRttiDynamicArrayType).ElementType.AsInstance.MetaclassType.Create; t.GetProperty('Propertys').getValue(myObject).setArrayElement(1,obj); obj:= (t.GetProperty('Propertys').PropertyType as TRttiDynamicArrayType).ElementType.AsInstance.MetaclassType.Create; t.GetProperty('Propertys').getValue(myObject).setArrayElement(2,obj); { myObject.Propertys[0] :=TSubProperty.Create; myObject.Propertys[0].item1 :='x'; myObject.Propertys[0].item2 :=1; myObject.Propertys[1] :=TSubProperty.Create; myObject.Propertys[1].item1 :='y'; myObject.Propertys[1].item2 :=2; myObject.Propertys[2] :=TSubProperty.Create; myObject.Propertys[2].item1 :='z'; myObject.Propertys[2].item2 :=3; ShowMessage(myObject.Propertys[2].item1); FreeAndNil(myObject.Propertys[2]); FreeAndNil(myObject.Propertys[1]); FreeAndNil(myObject.Propertys[0]); } FreeAndNil(myObject); end; { TSubProperty } procedure TSubProperty.Setitem1(const Value: String); begin Fitem1 := Value; end; procedure TSubProperty.Setitem2(const Value: Integer); begin Fitem2 := Value; end; { TmyObject } procedure TmyObject.SetPropertys(const Value: TArraySubPropertys); begin FPropertys := Value; end; end. 编辑: 此代码更改了数组的长度,但错误. procedure TForm3.Button3Click(Sender: TObject); var myObject:TmyObject; ctx : TRttiContext; t : TRttiType; v:TValue; len:Longint; p:pointer; begin myObject :=TmyObject.Create; ctx := TRttiContext.Create; t := ctx.GetType(myObject.ClassType); V := t.GetField('FPropertys').GetValue(myObject); len:=5; p:=v.GetReferenceToRawData; ShowMessage(inttostr(integer(@myObject.FPropertys))); //19795652 ShowMessage(inttostr(integer(p))); //19795672 DynArraySetLength(p,v.TypeInfo,1,@len); t.GetField('FPropertys').SetValue(myObject,v); ShowMessage(inttostr(length(myObject.Propertys))); //array length=19736192 ??? end; 编辑2: @Robert Love,谢谢你的回复,但问题还在继续. 点击button2 procedure TForm7.Button2Click(Sender: TObject); var myObject:TmyObject; ctx : TRttiContext; t : TRttiType; v : Tvalue; p : Pointer; Len : Longint; begin myObject :=TmyObject.Create; ctx := TRttiContext.Create; t := ctx.GetType(myobject.ClassType); V := t.GetProperty('Propertys'); Len := 3; P := V.GetReferenceToRawData; DynArraySetLength(P,V.TypeInfo,@Len); // error invalid pointer operation ShowMessage(inttostr(length(myObject.Propertys))); end; 解决方法
您可以使用DynArraySetLength函数.
var ... V : TValue; Len : LongInt; P : Pointer; begin ... V := t.GetProperty('Propertys'); Len := 3; P := V.GetReferenceToRawData; DynArraySetLength(P,@Len); ... end; 我在TArrayElementAdd类的RttiUtils.pas中使用此方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |