Форум: "Основная";
Текущий архив: 2018.10.28;
Скачать: [xml.tar.bz2];
ВнизArray в RTTI (D7) Найти похожие ветки
← →
mfender (2013-02-02 21:07) [0]Совсем не соображу как поступить. Уже и так и эдак повернул - не получается.
Беда в неосознании моём RTTI. В недостаточном сознании.
function ObjectToJSON(const AObj: TObject): TlkJSONObject;
var
I: Integer;
Cls: TClass;
PropCnt: Integer;
TypeData: PTypeData;
PropList: PPropList;
PropInfo: PPropInfo;
V: Variant;
begin
try
Result := TlkJSONObject.Create(True);
TypeData := GetTypeData(AObj.ClassInfo);
if TypeData.PropCount > 0 then
begin
GetMem(PropList, SizeOf(PropInfo) * TypeData.PropCount);
try
TypInfo.GetPropInfos(AObj.ClassInfo, PropList);
for I := 0 to Pred(TypeData.PropCount) do
begin
case PropList[I].PropType^.Kind of
tkSet:
Result.Add(PropList[I]^.Name, GetSetProp(AObj, PropList[I]));
tkEnumeration, tkInteger:
Result.Add(PropList[I]^.Name, GetOrdProp(AObj, PropList[I]));
tkFloat:
Result.Add(PropList[I]^.Name, GetFloatProp(AObj, PropList[I]));
tkString, tkLString, tkWString:
Result.Add(PropList[I]^.Name, GetStrProp(AObj, PropList[I]));
tkClass:
Result.Add(PropList[I]^.Name,
ObjecttoJSON(GetObjectProp(AObj, PropList[I])) as TlkJSONBase);
tkArray, tkDynArray:
{ Вот тут я очень не пойму что делать. GetVariantProp() отвечает что Variant и Array - суть разные вещи. Меня это не удивляет, но я просто ума не приложу никак, что нужно с этим сделать? }
Result.Add(PropList[I]^.Name,
ArrayToJSON(GetVariantProp(AObj, PropList[I])) as TlkJSONBase);
tkVariant:
begin
V := GetVariantProp(AObj, PropList[I]);
case TVarData(V).VType of
varString:
Result.Add(PropList[I]^.Name, VarToStr(V));
end;
end;
tkRecord:
{ А вот тут я вообще в заблуждении. Как пройти по всем "пунктам" record? }
Continue;
end;
end;
finally
FreeMem(PropList, SizeOf(PropInfo) * TypeData.PropCount);
end;
end;
except
end;
end;
function ArrayToJSON(const Arr: array of const): TlkJSONList;
var
I: Integer;
begin
Result := TlkJSONList.Create;
for I := Low(Arr) to High(Arr) do
begin
case Arr[I].VType of
vtObject: Result.Add(ObjectToJSON(Arr[I].VObject));
end;
end;
end;
На ArrayToJSON() внимания не обращайте. До неё всё равно ничего пока не доходит. От столба написал.
← →
Sapersky (2013-02-02 22:57) [1]В published properties не может быть массивов/рекордов.
Константы tkArray, tkDynArray, tkRecord - это для внутренней RTTI, которая нужна для обеспечения работы managed-типов (строк, дин. массивов и пр.).
← →
mfender (2013-02-03 00:02) [2]
> Sapersky (02.02.13 22:57) [1]
>
> В published properties не может быть массивов/рекордов.
> Константы tkArray, tkDynArray, tkRecord - это для внутренней
> RTTI, которая нужна для обеспечения работы managed-типов
> (строк, дин. массивов и пр.).
Тем не менее...
TRequestParamObject = class
private
FParamKey: string;
FParamValue: Variant;
published
property ParamKey: string read FParamKey write FParamKey;
property ParamValue: Variant read FParamValue write FParamValue;
end;
TReqParams = array of TRequestParamObject;
TRequestParamsCollection = class
private
FItems: TReqParams;
function GetItem(Idx: Integer): TRequestParamObject;
procedure SetItem(Idx: Integer; AItem: TRequestParamObject);
function GetJSON: TlkJSONList;
procedure SetJSON(const Value: TlkJSONList);
public
procedure Add(Idx: Integer; Key: string; Value: Variant); overload;
procedure Add(Key: string; Value: Variant); overload;
property Item[idx: Integer]: TRequestParamObject read GetItem write SetItem;
property JSON: TlkJSONList read GetJSON write SetJSON;
published
property Items: TReqParams read FItems write FItems;
end;
И в этом случае, как ни крути, TRequestParamsCollection.Items - tkArray в вышеозначенном случае.
Иначе нахрена бы мне вообще спрашивать обо всём этом?
← →
Sapersky (2013-02-03 01:11) [3]В D5 не компилируется. Я думал, все старые версии одинаковы в этом смысле.
Реально-то там есть RTTI, т.е. при трассировке в ветку tkArray, tkDynArray заходит? (в данном случае это tkDynArray)
D7 у меня нет, могу только погадать по XE3... но там extended RTTI и следовательно много нового по сравнению с D7. TypInfo.GetDynArrayProp, например, есть?
Ну или посмотри TypInfo.TTypeData, есть ли там секция tkDynArray.
← →
mfender (2013-02-03 08:07) [4]Нет такого, в том-то вся беда.
http://i53.fastpic.ru/big/2013/0203/52/8397fc4b5682ce195842870b27e80552.png
Поэтому пока забил костыль путём собственного геттера в коллекции, который сериализует массив Items в JSON, потом уже добавляю его в JSON верхнего объекта. Не бог весть какое, но всё же решение. Просто очень уж хочется сделать достаточно универсальную функцию. )))
← →
Sapersky (2013-02-03 19:45) [5]Здесь похожий вопрос:
http://stackoverflow.com/questions/4113480/rtti-how-get-values-of-dynamic-array-declared-as-class-property
Правда, в деталях решение проблемы не описывается. Вроде бы автор скопипастил нужный код из старших версий и у него заработало. Как-то так:
const
PROPSLOT_MASK = $FF000000;
PROPSLOT_FIELD = $FF000000;
function IsField(P: Pointer): Boolean; inline;
begin
Result := (DWord(P) and PROPSLOT_MASK) = PROPSLOT_FIELD;
end;
function GetField(Instance: TObject; P: Pointer): Pointer;
begin
Result := Pointer(DWord(Instance) + DWord(P) and not PROPSLOT_MASK);
end;
function ArrayToStr(Obj: TObject; Prop : PPropInfo): String;
Type
DByteArr = array of Byte;
Var
p : Pointer;
n, Cnt : Integer;
begin
If not IsField(Prop.GetProc) then begin Result := ""; Exit; end;
p := GetField(Obj, Prop.GetProc);
// упрощённый вариант GetDynArrayProp, только для свойств без геттеров
Cnt := Length(DByteArr(p^));
Result := InttoStr(Cnt) + " ";
// не знаю, можно ли в D7 можно получить тип элемента массива
// Prop.PropType^.TypeData.elType - есть такое?
// пока тип жёстко забит...
for n := 0 to Cnt-1 do
Result := Result + TReqParams(p^)[n].FParamKey + " ";
end;
← →
mfender (2013-02-03 22:30) [6]Спасибо, попробую из этого что-нибудь с утра выкроить. Может чего и получится.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2018.10.28;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.001 c