Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2018-07

How to find address of record member

5 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

Say I have a record type defined like this:

  TAppData = packed record  //Total 8 bytes per app
    ActiveToken: word; //Matches constant for app if active
    Option: word;      //16 option bits
    ExpDate: word;     //Integer TDateTime values
    Info: word;        //16 info bits
  end;

The data is stored in a security dongle memory which can be accessed only a word at a time by its word address 0..55.

I want to write my code such that the address to the individual member is calculated automatically so if the record type is modified it will still work.

So far I have this for the setter:
//Info is 4th member of record
address := AppBase + (AppNumber -1) * (SizeOf(TAppData) div 2) + 3;
WriteMemory(address, Value);

Appbase is defined in a global constants unit as where the array of app records in dongle memory starts.

While programming I have found that mistakes are easy if fixed offset constants are used, like 3 in the example.

Is there some way to get the address within the record of a member value?

Bo Berglund Developer in Sweden

Reply by email

Martin
to Bo Berglund
Bo Berglund wrote 16 lines
Say I have a record type defined like this: TAppData = packed record //Total 8 bytes per app ActiveToken: word; //Matches constant for app if active Option: word; //16 option bits ExpDate: word; //Integer TDateTime values Info: word; //16 info bits end; The data is stored in a security dongle memory which can be accessed only a word at a time by its word address 0..55. I want to write my code such that the address to the individual member is calculated automatically so if the record type is modified it will still work.
var AppData: TAppData absolute 0;
begin
writeln( ptrint( @AppData.Option ));

You can also take a variable without "absolute"
@AppData.Option - @AppData

Reply by email

Bo Berglund
to Martin
Martin wrote 24 lines
On 08/07/2018 17:07, Bo Berglund wrote: > Say I have a record type defined like this: > > TAppData = packed record //Total 8 bytes per app > ActiveToken: word; //Matches constant for app if active > Option: word; //16 option bits > ExpDate: word; //Integer TDateTime values > Info: word; //16 info bits > end; > > The data is stored in a security dongle memory which can be accessed > only a word at a time by its word address 0..55. > > I want to write my code such that the address to the individual member > is calculated automatically so if the record type is modified it will > still work. > var AppData: TAppData absolute 0; begin writeln( ptrint( @AppData.Option )); You can also take a variable without "absolute" @AppData.Option - @AppData
I tried this:
var
  offs: word;
begin
  ...
  offs := @FAppData.Info - @FAppData; //Info is 4th member of record
  address := AppBase + (AppNumber -1) * (SizeOf(TAppData) div 2) +
offs;
But it was not accepted by the compiler (on the offs := line)...
Error: Operator not applicable to this operand type

FAppData is declared in the class definition like this: TDongle = class

  private
    { Private declarations }
    FAppNumber,
    FKeySerial,
    FKeyFound: boolean;
    FAppData: TAppData;
    ....

I don't know the command 'absolute' and how it can be applied here in a class definition.

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote 11 lines
I tried this: var offs: word; begin ... offs := @FAppData.Info - @FAppData; //Info is 4th member of record address := AppBase + (AppNumber -1) * (SizeOf(TAppData) div 2) + offs; But it was not accepted by the compiler (on the offs := line)... Error: Operator not applicable to this operand type

But typecasting the operation fixed the problem:

  offs := Cardinal(@FAppData.Info) - Cardinal(@FAppData);

No compiler errors here anymore.

Bo Berglund Developer in Sweden

Reply by email

Martin
to Bo Berglund
Bo Berglund wrote 5 lines
But typecasting the operation fixed the problem: offs := Cardinal(@FAppData.Info) - Cardinal(@FAppData); No compiler errors here anymore.

May be a result of {$TYPEDADDRESS On} which may be default in some mode switches.

Untyped pointers seem to be subtract-able. But typed pointers of different type.....

Reply by email