Seems like I need a little more help to get this working.
Based on TypInfo, the record structure for a tkMethod is described like this:
tkMethod:
(MethodKind : TMethodKind;
ParamCount : Byte;
ParamList : array[0..1023] of Char
{in reality ParamList is a array[1..ParamCount] of:
record
Flags : TParamFlags;
ParamName : ShortString;
TypeName : ShortString;
end;
followed by
ResultType : ShortString // for mkFunction, mkClassFunction only
ResultTypeRef : PPTypeInfo; // for mkFunction, mkClassFunction only
CC : TCallConv;
ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
);
To avoid doing pointer calculations, I have created the following records:
{$PACKRECORDS 1}
TDMethodParamInfo = {$IFNDEF FPC_REQUIRES_PROPER_ALIGNMENT}packed{$ENDIF}
record
Flags : TParamFlags;
ParamName : ShortString;
TypeName : ShortString;
end;
{$PACKRECORDS C}
TDFunctionTypeData = {$IFNDEF FPC_REQUIRES_PROPER_ALIGNMENT}packed{$ENDIF}
record
MethodKind : TMethodKind;
ParamCount : Byte;
ParamList : array[1..1] of TDMethodParamInfo;
ResultType : ShortString;
ResultTypeRef : PPTypeInfo;
CC : TCallConv;
ParamTypeRefs : array[1..1] of PPTypeInfo;
end;
TDProcedureTypeData = {$IFNDEF FPC_REQUIRES_PROPER_ALIGNMENT}packed{$ENDIF}
record
MethodKind : TMethodKind;
ParamCount : Byte;
ParamList : array[1..1] of TDMethodParamInfo;
CC : TCallConv;
ParamTypeRefs : array[1..1] of PPTypeInfo;
end;
{$PACKRECORDS 1}
PDFunctionTypeData = ^TDFunctionTypeData;
PDProcedureTypeData = ^TDProcedureTypeData;
However, when I execute the following procedure:
procedure LoadParameters(const ATypeData: TDProcedureTypeData);
begin
WriteLn('> Name: ', ATypeData.ParamList[1].ParamName);
WriteLn('> ------------------------------------------');
WriteLn('> Type: ', ATypeData.ParamList[1].TypeName);
WriteLn('> ------------------------------------------');
WriteLn('> Kind: ', ATypeData.ParamTypeRefs[1]^^.Kind);
end;
I end up with this output:
> Name: AInput
> ------------------------------------------
> Type:
> ------------------------------------------
An unhandled exception occurred at $00427FFD :
EAccessViolation : Access violation
$00427FFD
$0042723C
$0042871F
$0042854F
$0042686C
$00401626
$00426540
$00401658
> Kind:
Before calling the procedure, I make sure that the data is for a mkProcedure:
if (ATypeData^.MethodKind = mkFunction) then
LoadParameters(PDFunctionTypeData(ATypeData)^)
else
LoadParameters(PDProcedureTypeData(ATypeData)^);
Anyone that can point out the flaw in the code? All classes are enclosed in {$M+}{$M-} so RTTI data should be available.
PS: The procedure only has 1 parameter hence I use array[1..1]. This also means that ParamTypeRefs shouldn't end up at the wrong offset unless there's something I'm missing.