AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Komplexe C-Struct ungleich "packed record" in Delphi
Thema durchsuchen
Ansicht
Themen-Optionen

Komplexe C-Struct ungleich "packed record" in Delphi

Ein Thema von Cookiemaster · begonnen am 26. Dez 2005 · letzter Beitrag vom 28. Dez 2005
Antwort Antwort
Cookiemaster

Registriert seit: 26. Dez 2005
7 Beiträge
 
#1

Komplexe C-Struct ungleich "packed record" in Delp

  Alt 26. Dez 2005, 21:36
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:
<-------- 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;
Hier eine Tabelle mit den Offset-Adressen der einzelnen struct/record-Member:
Code:
:                                             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
Ich hab mir schon überlegt, ob ich in Delphi "Dummy-Felder" einfügen soll um das Record der Struct anzupassen.
Aber vielleicht gibt es noch eine Einstellungsmöglichkeit, damit der Delphi-Compiler automatisch C-kompatible records erzeugt?
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#2

Re: Komplexe C-Struct ungleich "packed record" in

  Alt 27. Dez 2005, 06:00
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.
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#3

Re: Komplexe C-Struct ungleich "packed record" in

  Alt 27. Dez 2005, 07:15
Hat der Tip von Robert Marquardt geklappt?
OT-Frage Womit hast du das Listing der Offsets erstellt? Oder war es Handarbeit ?
Gruß, Jan
  Mit Zitat antworten Zitat
Cookiemaster

Registriert seit: 26. Dez 2005
7 Beiträge
 
#4

Re: Komplexe C-Struct ungleich "packed record" in

  Alt 27. Dez 2005, 22:15
Zitat von Robert Marquardt:
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.
Das ist das erste mal, dass ich in Delphi eine DLL & C-Struct verwende und ich hab mich natürlich informiert wie das geht - DLL Funktionen importieren, Structs in Records umwandeln... und AFAIK stand da immer man soll "packed record" verwenden.
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 von Der Jan:
OT-Frage Womit hast du das Listing der Offsets erstellt? Oder war es Handarbeit ?
Ich hab www.ultraedit.com benutzt (Spaltenbearbeitung und Makros sind damit möglich) um das zu erzeugen:
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) ) );
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#5

Re: Komplexe C-Struct ungleich "packed record" in

  Alt 28. Dez 2005, 05:19
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.139 Beiträge
 
Delphi 12 Athens
 
#6

Re: Komplexe C-Struct ungleich "packed record" in

  Alt 28. Dez 2005, 05:39
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz