2016-08-09 6 views
1

ich Code von Delphi nach C++ umgeschrieben und hier ist eine Linie, die ich nicht übersetzen kann:Delphi LongRec() Func in C++

typedef vector<char> ByteArray; 

unsigned char Bytes[4]; 

Buf[sCP + J] = LongRec(R).Bytes[3 - I]; 

scp, J, R und I-Variablen sind Ints.

Google sagt "LongRec deklariert einen Datensatz, der die verschiedenen Teile des angegebenen Werts als Typ Word oder Byte speichert." aber ich kann immer noch nicht verstehen, wie man es in C++ macht

+0

Im Prinzip wird 'int32' nach' int8 [4] 'typisiert und ein Element gelesen. –

Antwort

3

In C++ würden Sie eine Union verwenden, aber beachten Sie, dass etwas anderes out wie Sie in undefiniert Verhalten ist. Es wird wahrscheinlich funktionieren auf die gleiche Weise wie in Delphi, aber nur auf der gleichen Plattform, d. H. Mit der gleichen ABI als Win32 oder Win64, abhängig von der Compilerziel in Delphi verwendet.

So in Delphi:

type 
    LongRec = packed record 
    case Integer of 
     0: (Lo, Hi: Word); 
     1: (Words: array [0..1] of Word); 
     2: (Bytes: array [0..3] of Byte); 
    end; 

Und "wörtlichen" C++ Übersetzung:

#pragma pack(push, 1) 
union LongRec 
{ 
    struct { unsigned short Lo, Hi; }; 
    struct { unsigned short Words[2]; }; 
    struct { unsigned char Bytes[4]; }; 
} 
#pragma pack(pop) 

(Die obige dass sizeof(short) == 2 geht davon aus, dass Variablen Little-Endian und dass die Strukturen vollständig überlappen, All das kann nicht für alle Plattformen der Fall sein.)

Aber wieder, wenn Sie das seco lesen möchten nd auf höchste Byte eines long und etwas tun, wie

byte2 = reinterpret_cast<LongRec *>(&myLongint)->Bytes[2]; 

das undefinierten Verhalten ist(obwohl es wahrscheinlich Arbeit auf dem gleichen Windows-Plattform als Delphi).

Das richtige Verhalten ist (langsamer, aber richtig):

byte2 = myLongint >> 16 & 0xFF; 

oder

myHiWord = myLongint >> 16 & 0xFFFF; 

Aber auch das davon ausgeht, dass ein Byte ein Oktett ist, was nicht immer der Fall ist. Mit anderen Worten, dies ist nicht portabel und funktioniert nur wie unter Windows 32 und 64 Bit.

+0

Die korrekte Übersetzung würde ein '#pragma pack (1)' in der 'union'-Deklaration enthalten, und dann müsste 'reinterpret_cast' wie folgt verwendet werden:' byte2 = reinterpret_cast (myLongint) .Bytes [2]; ', oder das:' byte2 = reinterpret_cast (& myLongint) -> Bytes [2]; ' –

+0

@Remy: danke. Ich werde es aktualisieren. –

+0

Ich habe es, danke! – askrav