2010-06-17 8 views
5

Quiero saber cómo convertir números de Big-endian a números nativos en Delphi. Estoy portar algo de código C++ en la que me encontré:cómo convertir números de endian grande a números nativos 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; 

No estoy familiarizado con C++, por lo que no entiendo lo que los operadores hacen.

+0

posible duplicado de [Cómo convertir Big Endian y la forma de darle la vuelta al el bit más alto?] (http://stackoverflow.com/questions/2882434/how-to-convert-big-endian-and-how-to-flip-the-highest-bit) –

Respuesta

16

La respuesta de Andreas es un buen ejemplo de cómo hacerlo en pascal puro, pero todavía se ve un poco incómodo, al igual que el código C++. En realidad, esto puede hacerse en una sola instrucción de montaje, a través del cual se depende de si se está utilizando de 32 bits o de 16 bits enteros:

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

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

No necesita especificar el convención de llamadas, al menos no para Delphi (no sé sobre Free Pascal). 'register' es el predeterminado. –

+2

¡Esta es * la * solución, entonces! –

+4

No * necesita * especificar la convención de llamada, @Michael, pero es útil incluirlo en funciones de ensamblador como esta ya que * requieren * una convención de llamada específica para funcionar correctamente. –

2

Para invertir el orden de los 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; 

Para invertir el orden de los bytes:

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; 

creo que el último es lo que busca. Sin embargo, es muy probable que existan soluciones más rápidas y elegantes.

Descargo de responsabilidad: podría estar totalmente equivocado. Me siento un poco confundido en este momento. ¡Espero que alguien más vea esta pregunta y brinde una respuesta más definitiva!

Cuestiones relacionadas