RTTI Delphi Создать как TV значение n-мерной матрицы
Добрый день,
TValue - это функция Delphi-2010 и выше RTTI.
Исходя из моего предыдущего вопроса, я попытался сделать рекуррентную функцию, возвращающую TValue как n-мерную. матрица (2D, 3D, 4D...)
например, эта процедура покажет n-мерную матрицу (она перечислит все элементы из n-мерной матрицы как переменную TValue):
Procedure Show(X:TValue);
var i:integer;
begin
if x.IsArray then
begin
for i:=0 to x.GetArrayLength-1 do
show(x.GetArrayElement(i));
writeln;
end else
write(x.ToString,' ');
end;
Я не понимаю, как создать функцию для создания из телевизора n-мерной матрицы. Например, мне нужна функция CreateDynArray(Dimensions: массив целых чисел; Kind:TTypeKind):TValue; и функция вернет TValue, который является динамическим массивом, который содержит измерения, например:
Возврат =CreateDynArray([2,3],tkInteger); вернет TValue как tkDynArray, и если я покажу (Return) будет список
0 0 0
0 0 0
Не прекращается. Из TValue я пытаюсь создать DynArray с n-измерениями
Procedure CreateArray(var Value:TValue; NewDimmension:integer; NewValue2Kind:TTypeKind; NewValue2:TValue; IsLast:Boolean);
var i:integer;
NewValue:TValue;
len:Longint;
begin
If Value.IsArray then// we have components in this dimension
begin
for i:=0 to Value.GetArrayLength-1 do// list all
begin
NewValue:=Value.GetArrayElement[i];
CreateArray(newValue,NewDimension,NewValue2Kind,NewValue2,IsLast);
Value.SetArrayElement(i,NewValue);
end;
end;
end else
begin
if isLast then
begin
len:=NewDimension;
DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len); //set length to NewDimension
for i:=0 to NewDimension-1 do //Fill all with 0
Value.SetArrayElement(i,NewValue2);
end else
begin
len:=NewDimension;
DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len);//I will create len TValues
end;
end;
var Index:array of integer;
Value:TValue;
ValuKind:TTypeKind;
......
......
....
Case token of
tokInt:
begin
ValueKind:=tkInteger;
Value:=0;
end;
.....
end;
Index:=GetIndexFromSintacticTree;//for example if i have int[20][30] index=[20,30]
for i:=0 to high(index) do
begin
if i = high(index) then CreateArray(Variable.Value,Index[i],ValueKind,Value,True)
else CreateArray(Variable.Value,Index[i],ValueKind,Value,False)
//Variable.Value is TValue
end;
//first TValue have 1 element, after that it will have 20 elements, and after that will have 20*30 elements
Большое спасибо и хорошего дня!
1 ответ
Чтобы динамически создать динамический массив, вам нужна ссылка на его структуру информации типа (PTypeInfo
) перейти к DynArraySetLength
; призвание DynArraySetLength
и передача ссылки на нулевой указатель - это то, как вы можете создать новый динамический массив. Если конкретная форма динамического массива еще не существует в вашей программе Delphi, не будет никаких конкретных PTypeInfo
указатель, который сгенерирует для вас компилятор. В этом случае вам нужно будет сгенерировать соответствующий PTypeInfo
Структура данных самостоятельно. Это возможно, хотя и утомительно.
Честно говоря, я бы порекомендовал вам использовать структуру, отличную от встроенных динамических массивов Delphi, для представления массивов в вашей языковой проблеме сценариев. В долгосрочной перспективе, вероятно, будет гораздо меньше работы, чем попытка динамически генерировать низкоуровневые данные RTTI, которые с большей вероятностью будут меняться от версии к версии теперь, когда они имеют абстракцию более высокого уровня в модуле Rtti.