Delphi 5 (string[80]) vs Delphi XE

Hi guys

i'm trying to convert a old application made with Delphi 5 to Delphi XE 5
The probleme i have right now is about String[80] and the Read  / Write procedure

i have a type like that

 Type TEnrMess = record
      Mess       : String[80]; 
      MessSuiv   : Word;
      Hint       : Word;
  end;

And i read/write this type to a File of TEnrMess

My probleme is that the string have changed from Delphi 5 to Delphi XE
i join the link of a simple of the probleme that can be compiled  on delphi 5 and  any Delphi XE

https://mega.co.nz/#!wV1VyZzY!1ha5oOxTg7L1WJAOXutUygkjq42aTeaQT58lVYfmXI0

This sample exacly show the probleme, Note that i need to read the the file correcly in the new version of Delphi

Thanks for any help

Christian
0
Christ
10/10/2014 2:43:28 PM
📁 embarcadero.delphi.general
📃 4258 articles.
⭐ 0 followers.

💬 14 Replies
👁️‍🗨️ 1937 Views

Jeff Overcash (TeamB) wrote:

> Christ Fill wrote:
> > {code} 
> > Type TEnrMess = packed record
> >        Mess       : String[80];
> >        MessSuiv   : Word;
> >        Hint       : Word;
> >    end;
> > {code}
> > 
> > Work in Delphi XE but not in Delphi 5 give EinOutError Read beyond end of file
> > The trick is that the file are allready generated in delphi 5 (saved) and i need to read it in
> > Delphi XE
> > 
> > i thinki will need to make a converter in Delphi 5 using your packed record ...
> 
> Both the writer and reader should agree on alignment of the record.  Because 
> your string[80] is actually 81 bytes long the next item is going to have padding 
> in before it it written if not packed.  I think you will find that the 
> sizeof(TEnrMsg) is different between D5 and XE5.  The difference is the byte 
> padding.  Using packed tells it not to align the record.  I think in D5 it was 
> word aligned (2 bytes), later it was changed to default to quadword (8 bytes).
> 
> You can try in your XE code to change the alignment for that record to word like
> 
> {$A2}
>    TEnrMess = record
>       name : string[80];
>       age  : Integer;
>       male : Boolean;
>    end;
> {$A8}
> 
> The above gives the following record sizes ( sizeof(TEnrMess) )
> 
> {$A8} 92 (default for XE)
> {$A4} 92
> {$A2} 88 (I think this was D5's default but do not recall)
> {$A1} 86 (equivalent to alignment off)
> 
> 
> Optimally though you should always pack your records if writing them to a file 
> so that changes in record alignment does not have the negative impacts you are 
> seeing.

Jeff,
Note that Christian has shown two different structures, I don't know which is correct.
(just noticed...)

-- 
Tom Brunberg
[email protected]
0
Tom
10/10/2014 1:01:01 AM
Christ Fill wrote:

> Hi guys
> 
> i'm trying to convert a old application made with Delphi 5 to Delphi XE 5
> The probleme i have right now is about String[80] and the Read  / Write procedure
> 
> i have a type like that
> 
>  Type TEnrMess = record
>       Mess       : String[80]; 
>       MessSuiv   : Word;
>       Hint       : Word;
>   end;
> 
> And i read/write this type to a File of TEnrMess
> 
> My probleme is that the string have changed from Delphi 5 to Delphi XE

Hi Christian,
Shortstring (and variations like string[80]) are still the same in XE5.
Please explain what the problem is, I and many others don't like to download files from the net, in
order to learn the problem.

It might be that the problem is related to memory alignment, inwhich case {$A1} might help.


-- 
Tom Brunberg
[email protected]
0
Tom
10/10/2014 3:25:15 PM
Perfect, here a sample code...
The error come from TCustomer  that use the name string[80],  thos code worke perfecly in Delphi 5 and Delphi XE, but its look like the data saved it's not the same  on each version
Like a said is your wanna see more specifily the trouble check my link (it's only source, and bin compiled from Delphi 5 and Delphi XE 5)


type
   TCustomer = Record
     name : string[80];
     age  : Integer;
     male : Boolean;
   end;
 
 var
   myFile   : File of TCustomer;  // A file of customer records
   customer : TCustomer;          // A customer record variable
 
 begin
   // Try to open the Test.cus binary file for writing to
   AssignFile(myFile, 'Test.cus');
   ReWrite(myFile);
 
   // Write a couple of customer records to the file
   customer.name := 'Fred Bloggs';
   customer.age  := 21;
   customer.male := true;
   Write(myFile, customer);
 
   customer.name := 'Jane Turner';
   customer.age  := 45;
   customer.male := false;
   Write(myFile, customer);
 
   // Close the file
   CloseFile(myFile);
 
   // Reopen the file in read only mode
   FileMode := fmOpenRead;
   Reset(myFile);
 
   // Display the file contents
   while not Eof(myFile) do
   begin
     Read(myFile, customer);
     if customer.male
     then ShowMessage('Man with name '+customer.name+
                      ' is '+IntToStr(customer.age))
     else ShowMessage('Lady with name '+customer.name+
                      ' is '+IntToStr(customer.age));
   end;
 
   // Close the file for the last time
   CloseFile(myFile);
 end;
0
Christ
10/10/2014 3:38:38 PM
Perfect, here a sample code...
The error come from TCustomer  that use the name string[80],  thos code worke perfecly in Delphi 5 and Delphi XE, but its look like the data saved it's not the same  on each version
Like a said is your wanna see more specifily the trouble check my link (it's only source, and bin compiled from Delphi 5 and Delphi XE 5)
https://mega.co.nz/#!wV1VyZzY!1ha5oOxTg7L1WJAOXutUygkjq42aTeaQT58lVYfmXI0


type
   TCustomer = Record
     name : string[80];
     age  : Integer;
     male : Boolean;
   end;
 
 var
   myFile   : File of TCustomer;  // A file of customer records
   customer : TCustomer;          // A customer record variable
 
 begin
   // Try to open the Test.cus binary file for writing to
   AssignFile(myFile, 'Test.cus');
   ReWrite(myFile);
 
   // Write a couple of customer records to the file
   customer.name := 'Fred Bloggs';
   customer.age  := 21;
   customer.male := true;
   Write(myFile, customer);
 
   customer.name := 'Jane Turner';
   customer.age  := 45;
   customer.male := false;
   Write(myFile, customer);
 
   // Close the file
   CloseFile(myFile);
 
   // Reopen the file in read only mode
   FileMode := fmOpenRead;
   Reset(myFile);
 
   // Display the file contents
   while not Eof(myFile) do
   begin
     Read(myFile, customer);
     if customer.male
     then ShowMessage('Man with name '+customer.name+
                      ' is '+IntToStr(customer.age))
     else ShowMessage('Lady with name '+customer.name+
                      ' is '+IntToStr(customer.age));
   end;
 
   // Close the file for the last time
   CloseFile(myFile);
 end;

Edited by: Christ Fill on Oct 10, 2014 8:40 AM
0
Christ
10/10/2014 3:40:16 PM
Christ Fill wrote:
> Hi guys
> 
> i'm trying to convert a old application made with Delphi 5 to Delphi XE 5
> The probleme i have right now is about String[80] and the Read  / Write procedure
> 
> i have a type like that
> 
>  Type TEnrMess = record
>       Mess       : String[80]; 
>       MessSuiv   : Word;
>       Hint       : Word;
>   end;
> 
> And i read/write this type to a File of TEnrMess
> 
> My probleme is that the string have changed from Delphi 5 to Delphi XE
> i join the link of a simple of the probleme that can be compiled  on delphi 5 and  any Delphi XE
> 
> https://mega.co.nz/#!wV1VyZzY!1ha5oOxTg7L1WJAOXutUygkjq42aTeaQT58lVYfmXI0
> 
> This sample exacly show the probleme, Note that i need to read the the file correcly in the new version of Delphi
> 
> Thanks for any help
> 
> Christian

Short string has not changed between D5 and XE5.  I do think that the default 
byte alignment has.  You should always used packed on records that are going to 
be streamed in and out of files so default alignment of the compiler doesn't 
matter between versions.

try this and see if it helps.

{code}
  Type TEnrMess = packed record
       Mess       : String[80];
       MessSuiv   : Word;
       Hint       : Word;
   end;
{code}

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
10/10/2014 3:41:28 PM
Christ Fill wrote:

> Perfect, here a sample code...
> The error come from TCustomer  that use the name string[80],  thos code worke perfecly in Delphi
> 5 and Delphi XE, but its look like the data saved it's not the same  on each version Like a said
> is your wanna see more specifily the trouble check my link (it's only source, and bin compiled
> from Delphi 5 and Delphi XE 5)
> https://mega.co.nz/#!wV1VyZzY!1ha5oOxTg7L1WJAOXutUygkjq42aTeaQT58lVYfmXI0
> 
> 
> type
>    TCustomer = Record
>      name : string[80];
>      age  : Integer;
>      male : Boolean;
>    end;
>  
>  var
>    myFile   : File of TCustomer;  // A file of customer records
>    customer : TCustomer;          // A customer record variable
>  
>  begin
>    // Try to open the Test.cus binary file for writing to
>    AssignFile(myFile, 'Test.cus');
>    ReWrite(myFile);
>  
>    // Write a couple of customer records to the file
>    customer.name := 'Fred Bloggs';
>    customer.age  := 21;
>    customer.male := true;
>    Write(myFile, customer);
>  
>    customer.name := 'Jane Turner';
>    customer.age  := 45;
>    customer.male := false;
>    Write(myFile, customer);
>  
>    // Close the file
>    CloseFile(myFile);
>  
>    // Reopen the file in read only mode
>    FileMode := fmOpenRead;
>    Reset(myFile);
>  
>    // Display the file contents
>    while not Eof(myFile) do
>    begin
>      Read(myFile, customer);
>      if customer.male
>      then ShowMessage('Man with name '+customer.name+
>                       ' is '+IntToStr(customer.age))
>      else ShowMessage('Lady with name '+customer.name+
>                       ' is '+IntToStr(customer.age));
>    end;
>  
>    // Close the file for the last time
>    CloseFile(myFile);
>  end;
> 
> Edited by: Christ Fill on Oct 10, 2014 8:40 AM

Please relief the tension and tell us what the showmessage displays?

-- 
Tom Brunberg
[email protected]
0
Tom
10/10/2014 3:46:08 PM
{code} 
Type TEnrMess = packed record
       Mess       : String[80];
       MessSuiv   : Word;
       Hint       : Word;
   end;
{code}

Work in Delphi XE but not in Delphi 5 give EinOutError Read beyond end of file
The trick is that the file are allready generated in delphi 5 (saved) and i need to read it in Delphi XE

i thinki will need to make a converter in Delphi 5 using your packed record ...
0
Christ
10/10/2014 5:49:08 PM
Christ Fill wrote:
> {code} 
> Type TEnrMess = packed record
>        Mess       : String[80];
>        MessSuiv   : Word;
>        Hint       : Word;
>    end;
> {code}
> 
> Work in Delphi XE but not in Delphi 5 give EinOutError Read beyond end of file
> The trick is that the file are allready generated in delphi 5 (saved) and i need to read it in Delphi XE
> 
> i thinki will need to make a converter in Delphi 5 using your packed record ...

Both the writer and reader should agree on alignment of the record.  Because 
your string[80] is actually 81 bytes long the next item is going to have padding 
in before it it written if not packed.  I think you will find that the 
sizeof(TEnrMsg) is different between D5 and XE5.  The difference is the byte 
padding.  Using packed tells it not to align the record.  I think in D5 it was 
word aligned (2 bytes), later it was changed to default to quadword (8 bytes).

You can try in your XE code to change the alignment for that record to word like

{$A2}
   TEnrMess = record
      name : string[80];
      age  : Integer;
      male : Boolean;
   end;
{$A8}

The above gives the following record sizes ( sizeof(TEnrMess) )

{$A8} 92 (default for XE)
{$A4} 92
{$A2} 88 (I think this was D5's default but do not recall)
{$A1} 86 (equivalent to alignment off)


Optimally though you should always pack your records if writing them to a file 
so that changes in record alignment does not have the negative impacts you are 
seeing.

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
10/10/2014 6:59:40 PM
Tom Brunberg wrote:
> Jeff Overcash (TeamB) wrote:
> 
> Jeff,
> Note that Christian has shown two different structures, I don't know which is correct.
> (just noticed...)
> 

I noticed, the other one (the one I switched to in the end) is a little more 
interesting because as elements it was 81, 4, 1 and the first was 81, 2, 2 which 
was not as interesting in showing how the sizeof changes according to the alignment.

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
10/10/2014 7:44:35 PM
Jeff Overcash (TeamB) wrote:

> Tom Brunberg wrote:
> > Jeff Overcash (TeamB) wrote:
> > 
> > Jeff,
> > Note that Christian has shown two different structures, I don't know which is correct.
> > (just noticed...)
> > 
> 
> I noticed, the other one (the one I switched to in the end) is a little more 
> interesting because as elements it was 81, 4, 1 and the first was 81, 2, 2 which 
> was not as interesting in showing how the sizeof changes according to the alignment.

ok

-- 
Tom Brunberg
[email protected]
0
Tom
10/10/2014 8:22:12 PM
Christ Fill wrote:

> {code} 
> Type TEnrMess = packed record
>        Mess       : String[80];
>        MessSuiv   : Word;
>        Hint       : Word;
>    end;
> {code}
> 
> Work in Delphi XE but not in Delphi 5 give EinOutError Read beyond
> end of file The trick is that the file are allready generated in
> delphi 5 (saved) and i need to read it in Delphi XE

Use some hex viewer to see real layout of bytes in files in both test
cases. After that you will know what to do.

--
Alex
0
Alex
10/12/2014 1:01:01 AM
Christ Fill wrote:

> Hi guys
> 
> i'm trying to convert a old application made with Delphi 5 to Delphi
> XE 5 The probleme i have right now is about String[80] and the Read
> / Write procedure
> 
> i have a type like that
> 
>  Type TEnrMess = record
>       Mess       : String[80]; 
>       MessSuiv   : Word;
>       Hint       : Word;
>   end;
> 
> And i read/write this type to a File of TEnrMess
> 
> My probleme is that the string have changed from Delphi 5 to Delphi XE
> i join the link of a simple of the probleme that can be compiled  on
> delphi 5 and  any Delphi XE
> 
>
https://mega.co.nz/#!wV1VyZzY!1ha5oOxTg7L1WJAOXutUygkjq42aTeaQT58lVYfmXI0
> 
> This sample exacly show the probleme

Not to me. I don't see an example .msg file I could try out.

Note that you may want to take care of alignment. It is probably best
to make the records packed in both versions, and do manual alignment
where that is necessary.

-- 
Rudy Velthuis        http://www.rvelthuis.de

Zymurgy's First Law Of Evolving System Dynamics: Once you open a 
can of worms, the only way to recan them is to use a larger can.
0
Rudy
10/12/2014 1:15:35 PM
Christ Fill wrote:

> {code} 
> Type TEnrMess = packed record
>        Mess       : String[80];
>        MessSuiv   : Word;
>        Hint       : Word;
>    end;
> {code}
> 
> Work in Delphi XE but not in Delphi 5 give EinOutError Read beyond
> end of file The trick is that the file are allready generated in
> delphi 5 (saved) and i need to read it in Delphi XE
> 
> i thinki will need to make a converter in Delphi 5 using your packed
> record ...

That is probably the best choice. Or you look at the file with a hex
editor and try to find out how things are aligned and you do manual
alignment to get exact the same format.

You can display the sizes of the records in both versions in a simple
test program, to see if they are the same size. Probably not.

-- 
Rudy Velthuis        http://www.rvelthuis.de

"You should never wear your best trousers when you go out to
 fight for freedom and liberty."
 -- Henrik Ibsen
0
Rudy
10/12/2014 1:17:50 PM
Hi guys

The {$A2},{$A8} do the trick, thx Jeff Overcash
you make my day ;)

Christian
0
Christ
10/14/2014 3:39:37 PM