![]() |
Komplexe C-Struct ungleich "packed record" in Delp
Hallo,
ich hab da ein merkwürdiges Problem mit der Umwandlung von C Structs nach Delphi 7. Normalerweise übersetzt man die ja zu "packed record", aber das passt trotzdem nicht. Delphi lässt bei "packed record" keinen Zwischenraum zwischen den Feldern, aber in dem C-Programm (MS Visual C++ 6.0) IST da teilweise ein Zwischenraum! Siehe Tabelle unten. Hier die Quellcodes gegenübergestellt. Wenn du Probleme hast den Code zu lesen, dann kopier ihn dir bitte in einen Texteditor damit die automatischen Zeilenumbrüche verschwinden.
Code:
Hier eine Tabelle mit den Offset-Adressen der einzelnen struct/record-Member:
<-------- C-Header -----------------------------> <-------- Delphi ----------------------------------------->
const #define MAX_PATH 260 MAX_PATH = 260; #define AUTORESPEXCLUDE_LEN 5001 AUTORESPEXCLUDE_LEN = 5001; #define MAILBOX_LEN 30 MAILBOX_LEN = 30; #define DOMAIN_LEN 45 DOMAIN_LEN = 45; #define EMAIL_LEN MAILBOX_LEN + DOMAIN_LEN + 1 EMAIL_LEN = MAILBOX_LEN + DOMAIN_LEN + 1; #define TIME_LEN 20 TIME_LEN = 20; type struct MD_AutoResponder { MD_AutoResponder = packed record char Script [MAX_PATH + 1]; Script : array[0..MAX_PATH ] of char; char Process [MAX_PATH + 1]; Process : array[0..MAX_PATH ] of char; char Exclude [AUTORESPEXCLUDE_LEN + 1]; Exclude : array[0..AUTORESPEXCLUDE_LEN] of char; char AddToList [EMAIL_LEN + 1]; AddToList : array[0..EMAIL_LEN ] of char; char RemoveFromList[EMAIL_LEN + 1]; RemoveFromList : array[0..EMAIL_LEN ] of char; char StartTime [TIME_LEN + 1]; StartTime : array[0..TIME_LEN ] of char; char EndTime [TIME_LEN + 1]; EndTime : array[0..TIME_LEN ] of char; bool PassMessage; PassMessage : boolean; }; end; const #define FWDADDR_LEN 256 FWDADDR_LEN = 256; #define FWDHOST_LEN 64 FWDHOST_LEN = 64; #define FWDSENDAS_LEN 128 FWDSENDAS_LEN = 128; #define FWDPORT_LEN 8 FWDPORT_LEN = 8; type struct MD_Forwarding { MD_Forwarding = packed record char Address[FWDADDR_LEN + 1]; Address : array[0..FWDADDR_LEN ] of char; char Host [FWDHOST_LEN + 1]; Host : array[0..FWDHOST_LEN ] of char; char SendAs [FWDSENDAS_LEN + 1]; SendAs : array[0..FWDSENDAS_LEN] of char; char Port [FWDPORT_LEN + 1]; Port : array[0..FWDPORT_LEN ] of char; }; end; const #define FULLNAME_LEN 30 FULLNAME_LEN = 30; #define MAILDIR_LEN 90 MAILDIR_LEN = 90; #define PASSWORD_LEN 20 PASSWORD_LEN = 20; #define MBXFORMAT_LEN 32 MBXFORMAT_LEN = 32; #define COMMENT_LEN 512 COMMENT_LEN = 512; #define USERDEFINED_LEN 256 USERDEFINED_LEN = 256; type struct MD_UserInfo { MD_UserInfo = packed record char Email [EMAIL_LEN + 1]; Email : array[0..EMAIL_LEN ] of char; char Mailbox [MAILBOX_LEN + 1]; Mailbox : array[0..MAILBOX_LEN ] of char; char Domain [DOMAIN_LEN + 1]; Domain : array[0..DOMAIN_LEN ] of char; char FullName [FULLNAME_LEN + 1]; FullName : array[0..FULLNAME_LEN] of char; char MailDir [MAILDIR_LEN + 1]; MailDir : array[0..MAILDIR_LEN ] of char; char Password [PASSWORD_LEN + 1]; Password : array[0..PASSWORD_LEN] of char; bool AutoDecode; AutoDecode : boolean; bool IsForwarding; IsForwarding : boolean; char AccessType; AccessType : char; bool AllowChangeViaEmail; AllowChangeViaEmail : boolean; bool KeepForwardedMail; KeepForwardedMail : boolean; bool HideFromEveryone; HideFromEveryone : boolean; bool EncryptMail; EncryptMail : boolean; bool ApplyQuotas; ApplyQuotas : boolean; bool EnableMultiPOP; EnableMultiPOP : boolean; bool CanModifyGAB; CanModifyGAB : boolean; long MaxMessageCount; MaxMessageCount : integer; long MaxDiskSpace; MaxDiskSpace : integer; int WebConfig; WebConfig : integer; char NTAccount [MAILBOX_LEN + 1]; NTAccount : array[0..MAILBOX_LEN ] of char; char MailFormat [MBXFORMAT_LEN + 1]; MailFormat : array[0..MBXFORMAT_LEN] of char; MD_Forwarding Forwarding; Forwarding : MD_Forwarding; MD_AutoResponder AutoResponder; AutoResponder : MD_AutoResponder; long MaxUIDLCount; MaxUIDLCount : integer; long MaxMessageSize; MaxMessageSize : integer; bool RecurseIMAP; RecurseIMAP : boolean; bool IsDisabled; IsDisabled : boolean; bool CheckAddrBook; CheckAddrBook : boolean; bool UpdateAddrBook; UpdateAddrBook : boolean; int MaxInactive; MaxInactive : integer; int MaxMessageAge; MaxMessageAge : integer; int MaxDeletedIMAPMessageAge; MaxDeletedIMAPMessageAge : integer; char Comments [COMMENT_LEN + 1]; Comments : array[0..COMMENT_LEN ] of char; char UserDefined [USERDEFINED_LEN + 1]; UserDefined : array[0..USERDEFINED_LEN] of char; }; end;
Code:
Ich hab mir schon überlegt, ob ich in Delphi "Dummy-Felder" einfügen soll um das Record der Struct anzupassen.
: MSVC++6 Delphi
char MD_UserInfo Email 0 0 char MD_UserInfo Mailbox 77 77 char MD_UserInfo Domain 108 108 char MD_UserInfo FullName 154 154 char MD_UserInfo MailDir 185 185 char MD_UserInfo Password 276 276 bool MD_UserInfo AutoDecode 297 297 bool MD_UserInfo IsForwarding 298 298 char MD_UserInfo AccessType 299 299 bool MD_UserInfo AllowChangeViaEmail 300 300 bool MD_UserInfo KeepForwardedMail 301 301 bool MD_UserInfo HideFromEveryone 302 302 bool MD_UserInfo EncryptMail 303 303 bool MD_UserInfo ApplyQuotas 304 304 bool MD_UserInfo EnableMultiPOP 305 305 bool MD_UserInfo CanModifyGAB 306 306 // bis hier ist alles OK long MD_UserInfo MaxMessageCount 308 307 // 1. Fehler um 1 Byte long MD_UserInfo MaxDiskSpace 312 311 int MD_UserInfo WebConfig 316 315 char MD_UserInfo NTAccount 320 319 char MD_UserInfo MailFormat 351 350 char MD_Forwarding Address 384 383 char MD_Forwarding Host 641 640 char MD_Forwarding SendAs 706 705 char MD_Forwarding Port 835 834 char MD_AutoResponder Script 844 843 char MD_AutoResponder Process 1105 1104 char MD_AutoResponder Exclude 1366 1365 char MD_AutoResponder AddToList 6368 6367 char MD_AutoResponder RemoveFromList 6445 6444 char MD_AutoResponder StartTime 6522 6521 char MD_AutoResponder EndTime 6543 6542 bool MD_AutoResponder PassMessage 6564 6563 long MD_UserInfo MaxUIDLCount 6568 6564 // 2. Fehler um weitere 3 Bytes long MD_UserInfo MaxMessageSize 6572 6568 bool MD_UserInfo RecurseIMAP 6576 6572 bool MD_UserInfo IsDisabled 6577 6573 bool MD_UserInfo CheckAddrBook 6578 6574 bool MD_UserInfo UpdateAddrBook 6579 6575 int MD_UserInfo MaxInactive 6580 6576 int MD_UserInfo MaxMessageAge 6584 6580 int MD_UserInfo MaxDeletedIMAPMessageAge 6588 6584 char MD_UserInfo Comments 6592 6588 char MD_UserInfo UserDefined 7105 7101 // Am Schluß stimmt die Objektgröße um ganze 6 Byte nicht! sizeof(UserInfo) 7364 7358 Aber vielleicht gibt es noch eine Einstellungsmöglichkeit, damit der Delphi-Compiler automatisch C-kompatible records erzeugt? |
Re: Komplexe C-Struct ungleich "packed record" in
Versuch mal das Alignmment mit {$ALIGN 4} zu setzen und packed zu entfernen.
Bis einschliesslich CanModifyGAB sind es alles Variablen mit Groesse 1 so dass der Compiler sie dicht an dicht legen kann. Beim Bytezugriff ist das Alignment egal. Erst bei MaxMessageCount beginnt das Alignment zu wirken. Es sollte uebrigens besser Longint sein. Der naechste Alignmentunterschied zeigt ganz genau das es ein Alignment auf 4 ist, denn es werden 3 Bytes ergaenzt. |
Re: Komplexe C-Struct ungleich "packed record" in
Hat der Tip von Robert Marquardt geklappt?
OT-Frage Womit hast du das Listing der Offsets erstellt? Oder war es Handarbeit ? :) |
Re: Komplexe C-Struct ungleich "packed record" in
Zitat:
Das C++ Projekt ist so eingestellt: "Struct-Element-Ausrichtung" = 8 Byte. Jedenfalls geht es jetzt ohne das packed und mit {$ALIGN 8}. Vielen Dank! Zitat:
![]()
Code:
Mainform.log.Lines.Add('@UserInfo.Email = ' + inttostr( integer(@UserInfo.Email ) - integer(@UserInfo) ) );
Mainform.log.Lines.Add('@UserInfo.Mailbox = ' + inttostr( integer(@UserInfo.Mailbox ) - integer(@UserInfo) ) ); Mainform.log.Lines.Add('@UserInfo.Domain = ' + inttostr( integer(@UserInfo.Domain ) - integer(@UserInfo) ) ); |
Re: Komplexe C-Struct ungleich "packed record" in
Ich bevorzuge immer noch den DOS Brief Editor dafuer :-)
Die regulaeren Ausdruecke sind sehr gut geeignet Header-Konversionen durchzufuehren. packed record ist deshalb sehr haeufig, da Microsoft frueher alle seine Strukturen gepackt hat. |
Re: Komplexe C-Struct ungleich "packed record" in
Da ja die genaue Struktur bekannt war, hätte man im Notfall immnoch einen Packed Record erstellen und dabei ein paar DummyBytes mit einfügen können ... falls es nicht geklappt so (siehe oben) geklappt hätte.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz