{$mode objfpc} {$warn 4055 off Conversion between ordinals and pointers is not portable} type PObject1 = ^Object1; Object1 = record field: int32; struct: record field: int64; ary: array[2 .. 5] of record x, y: int32; bottomAry: record n: SizeUint; items: array[3 .. 6, 4 .. 6] of uint16; end; end; end; end; PTopLevelArray = ^TopLevelArray; TopLevelArray = array[1 .. 3] of Object1; TopLevelClass = class objs: array[1 .. 3] of Object1; end; const OffsetOf3YInObject1 = PtrUint(@PObject1(nil)^.struct.ary[3].y); OffsetOf2345InObject1 = PtrUint(@PObject1(nil)^.struct.ary[3].bottomAry.items[4, 5]); OffsetOf23YInTopLevelArray = PtrUint(@PTopLevelArray(nil)^[2].struct.ary[3].y); OffsetOf2345InTopLevelArray = PtrUint(@PTopLevelArray(nil)^[2].struct.ary[3].bottomAry.items[4, 5]); OffsetOf23YInTopLevelClass = PtrUint(@TopLevelClass(nil).objs[2].struct.ary[3].y); OffsetOf2345InTopLevelClass = PtrUint(@TopLevelClass(nil).objs[2].struct.ary[3].bottomAry.items[4, 5]); function RecoverObject1From3Y(_3Y: PInt32): PTopLevelArray; begin result := pointer(_3Y) - PtrUint(@PObject1(nil)^.struct.ary[3].y); end; function RecoverObject1From345(_345: PUint16): PTopLevelArray; begin result := pointer(_345) - PtrUint(@PObject1(nil)^.struct.ary[3].bottomAry.items[4, 5]); end; function RecoverTopLevelArrayFrom23Y(_23Y: PInt32): PTopLevelArray; begin result := pointer(_23Y) - PtrUint(@PTopLevelArray(nil)^[2].struct.ary[3].y); end; function RecoverTopLevelArrayFrom2345(_2345: PUint16): PTopLevelArray; begin result := pointer(_2345) - PtrUint(@PTopLevelArray(nil)^[2].struct.ary[3].bottomAry.items[4, 5]); end; function RecoverTopLevelClassFrom23Y(_23Y: PInt32): TopLevelClass; begin result := TopLevelClass(pointer(_23Y) - PtrUint(@TopLevelClass(nil).objs[2].struct.ary[3].y)); end; function RecoverTopLevelClassFrom2345(_2345: PUint16): TopLevelClass; begin result := TopLevelClass(pointer(_2345) - PtrUint(@TopLevelClass(nil).objs[2].struct.ary[3].bottomAry.items[4, 5])); end; var o1: Object1; tla: TopLevelArray; tlc: TopLevelClass; fieldPtr, recovered: pointer; begin tlc := nil; try fieldPtr := @o1.struct.ary[3].y; recovered := RecoverObject1From3Y(fieldPtr); if recovered <> @o1 then begin writeln('@o1 = ', HexStr(@o1), ', @o1.struct.ary[3].y = ', HexStr(fieldPtr), ', recovered = ', HexStr(recovered)); halt(1); end; fieldPtr := @o1.struct.ary[3].bottomAry.items[4, 5]; recovered := RecoverObject1From345(fieldPtr); if recovered <> @o1 then begin writeln('@o1 = ', HexStr(@o1), ', @o1.struct.ary[3].bottomAry.items[4, 5] = ', HexStr(fieldPtr), ', recovered = ', HexStr(recovered)); halt(2); end; fieldPtr := @tla[2].struct.ary[3].y; recovered := RecoverTopLevelArrayFrom23Y(fieldPtr); if recovered <> @tla then begin writeln('@tla = ', HexStr(@tla), ', @tla[2].struct.ary[3].y = ', HexStr(fieldPtr), ', recovered = ', HexStr(recovered)); halt(3); end; fieldPtr := @tla[2].struct.ary[3].bottomAry.items[4, 5]; recovered := RecoverTopLevelArrayFrom2345(fieldPtr); if recovered <> @tla then begin writeln('@tla = ', HexStr(@tla), ', @tla[2].struct.ary[3].bottomAry.items[4, 5] = ', HexStr(fieldPtr), ', recovered = ', HexStr(recovered)); halt(4); end; tlc := TopLevelClass.Create; fieldPtr := @tlc.objs[2].struct.ary[3].y; recovered := RecoverTopLevelClassFrom23Y(fieldPtr); if recovered <> pointer(tlc) then begin writeln('tlc = ', HexStr(tlc), ', @tlc.objs[2].struct.ary[3].y = ', HexStr(fieldPtr), ', recovered = ', HexStr(recovered)); halt(5); end; fieldPtr := @tlc.objs[2].struct.ary[3].bottomAry.items[4, 5]; recovered := RecoverTopLevelClassFrom2345(fieldPtr); if recovered <> pointer(tlc) then begin writeln('tlc = ', HexStr(tlc), ', @tlc.objs[2].struct.ary[3].bottomAry.items[4, 5] = ', HexStr(fieldPtr), ', recovered = ', HexStr(recovered)); halt(6); end; writeln('ok'); finally tlc.Free; end; end.