How to find address of record member

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

How to find address of record member

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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to find address of record member

Martin Friebe
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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to find address of record member

Bo Berglund
On Sun, 8 Jul 2018 17:16:01 +0200, Martin
<[hidden email]> wrote:

>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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to find address of record member

Bo Berglund
On Sun, 08 Jul 2018 18:28:34 +0200, Bo Berglund
<[hidden email]> wrote:

>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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to find address of record member

Martin Friebe
On 08/07/2018 19:08, Bo Berglund wrote:
> 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.....
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal