Link to home
Start Free TrialLog in
Avatar of shardt
shardt

asked on

Record Type will not port from Delphi 4 to Delphi 2005. Record size does not match causing the data to load incorrectly.

I have the following record that was originally created in Delphi 4. I now have Delphi 2005. When I try to load this record header the data is corrupt. When I check the size of the record header it is 60 bytes and should be 57, which it is in Delphi 4. Where did the other 3 bytes come from and how do I fix this so the records load correctly in Delphi 2005?

tVersionHeader=record
    version: String[10];
    Application: String[25];
    Updated: TSystemTime;
    Size: LongInt;
    end;
Avatar of Jase-Coder
Jase-Coder

try doing:

tVersionHeader=record
    version: String;
    Application: String;
    Updated: TSystemTime;
    Size: LongInt;
    end;
Avatar of kretzschmar
maybe also

tVersionHeader= packed record
    version: String[10];
    Application: String[25];
    Updated: TSystemTime;
    Size: LongInt;
    end;


no d2005 on hand

meikl ;-)
Avatar of shardt

ASKER

Thanks, for the quick response. I have to specify string lengths as the data is stored on disk. I also tried the packed record and this did not resolve the problem ether.
when anything did go wrong i would suspect TSystemTime is in delphi 2005 not that what it used to be in delphi 4. however, you should be able to findout yourself with a couple of tests:

- hold CTRL-key and leftclick on TSystemTime with the mouse. this should open you the declaration of it. do it in d4 and in d2005 and check for differences
- same as above, but check the help files instead. in d4 i think TSystemTime comes down to the win32 api type "SYSTEMTIME", but i have no clue if it something completely else in d2005
- do length() operations on each record member. here is what i expect:

  length(.version) = 11    // 10 characters string + 1 for size
  length(.Application) = 26    // 25 for content, 1 for size
  length(.Updated) = 16    // because SYSTEMTIME has 8 times a WORD member
  length(.Size)  = 4    // longint is 32bit: 32 divided by 8 give 4 bytes.

  //  11 + 26 + 16 + 4 = 57


like i said :) i suspect TSystemTime. therefore i think your record above would work if you would find the declaration on SYSTEMTIME in d4 and copy it to d2005 (of course name it to something else, like "TSystemTime_D4 = record") and use that type instead. hope you got it the same way i tried to write it :P
i guessed more on aligned record-members,
but well, no d2005 on hand, so another type-declaration may possible as amigo describes :-))
keyword "packed" will solve this:

type
  TVersionHeader = packed record
    version     : string[10];
    Application : string[25];
    Updated     : TSystemTime;
    Size        : LongInt;
  end;
ou.. looks like some discussion has started while i was "answering", lol..
sorry, don't know how to solve in d2005
Avatar of shardt

ASKER

I have compared both D4 & D2005 TSystemTime records and no difference. I have also checked the length of all the elements and all the length match as stated.

 SizeOf(version) = 11    
 SizeOfApplication) = 26    
 SizeOf(Updated) = 16  
 SizeOf(Size)  = 4  

However if you do a SizeOf(TVersionHeader) you get 60 in D2005 and 57 in D4.
"I also tried the packed record" <-- and what about alternatives of keyword "packed"? Is there any in D2005?
maybe also some newer "code optimization" which is turned on in d2005? check project options and turn off anything suspicious
Avatar of shardt

ASKER

I am unsure what has changed but got the total record size now to 57 as it should be, however the size element is still not being read correctly. It should be 337 and the value that is being read is nowhare near this. I have looked through the compiler setting and it all matches as to what I have setup in D4. I also rechecked the TSystemTime structure and they also match. I tryed using the packed record and it had no effect.
I have got Delphi 7 and just checked
TVersionHeader=packed record == 57 Byte
TVersionHeader=record == 60 Byte

this record is 60 byte with and without the reserved word packed
type
  TVersionHeader = record
    version     : string[11]; //11+1 mod 4 = 0
    Application : string[27];//27+1 mod 4 = 0
    Updated     : TSystemTime;
    Size        : LongInt;
  end;

Using packed slows data access.
Memory manager blocks are always rounded upward to a 4-byte boundary. which guarantees optimal CPU performance when addressing the block.
(unless explicitly specified otherwise)
Avatar of shardt

ASKER

Here is the problem, I need to be able to read the current db on disk. The db header currently on disk is 57. What is the best way to resolve this problem without blowing up the current db and starting from scratch? Using packed record did not help in reading the data correctly off of the disk.
ASKER CERTIFIED SOLUTION
Avatar of piba
piba

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial