2010-06-17 7 views
5

Je veux savoir comment convertir les nombres big-endian en nombres natifs en Delphi. Je suis un peu PORTAGE C++ code que je suis tombé sur:comment convertir les nombres big-endian en nombres natifs delphi

unsigned long blockLength = *blockLengthPtr++ << 24; 
blockLength |= *blockLengthPtr++ << 16; 
blockLength |= *blockLengthPtr++ << 8; 
blockLength |= *blockLengthPtr; 

unsigned long dataLength = *dataLengthPtr++ << 24; 
dataLength |= *dataLengthPtr++ << 16; 
dataLength |= *dataLengthPtr++ << 8; 
dataLength |= *dataLengthPtr; 

Je ne suis pas familier avec le C++, donc je ne comprends pas ce que les opérateurs font.

+0

duplication possible de [Comment convertir Big Endian et comment retourner le le plus haut bit?] (http://stackoverflow.com/questions/2882434/how-to-convert-big-endian-and-how-to-flip-the-highest-bit) –

Répondre

16

La réponse d'Andreas est un très bon exemple de la façon de le faire en purcal, mais il semble encore un peu bizarre, tout comme le code C++. Cela peut en fait être fait dans une seule instruction d'assemblage, bien que celle-ci dépende de l'utilisation d'entiers 32 bits ou 16 bits:

function SwapEndian32(Value: integer): integer; register; 
asm 
    bswap eax 
end; 

function SwapEndian16(Value: smallint): smallint; register; 
asm 
    xchg al, ah 
end; 
+0

Vous n'avez pas besoin de spécifier le convention d'appel, au moins pas pour Delphi (ne sais pas à propos de Free Pascal). 'register' est la valeur par défaut. –

+2

C'est * la * solution, alors! –

+4

Vous n'avez pas * besoin * de spécifier la convention d'appel, @Michael, mais il est utile de l'inclure dans les fonctions d'assembleur comme ceci, car elles * requièrent * une convention d'appel spécifique pour fonctionner correctement. –

2

Pour inverser l'ordre des bits:

procedure SwapEndiannessOfBits(var Value: cardinal); 
var 
    tmp: cardinal; 
    i: Integer; 
begin 
    tmp := 0; 
    for i := 0 to 8*sizeof(Value) - 1 do 
    inc(tmp, ((Value shr i) and $1) shl (8*sizeof(Value) - i - 1)); 
    Value := tmp; 
end; 

Pour inverser l'ordre des octets:

procedure SwapEndiannessOfBytes(var Value: cardinal); 
var 
    tmp: cardinal; 
    i: Integer; 
begin 
    tmp := 0; 
    for i := 0 to sizeof(Value) - 1 do 
    inc(tmp, ((Value shr (8*i)) and $FF) shl (8*(sizeof(Value) - i - 1))); 
    Value := tmp; 
end; 

Je pense que le dernier est ce que vous recherchez. Très probablement, il existe des solutions plus rapides et plus élégantes.

Avertissement: Je peux me tromper totalement. Je me sens un peu confus pour le moment. J'espère que quelqu'un d'autre verra cette question et fournira une réponse plus définitive!

Questions connexes