Як правильно масив байт привести до integer

Читаю буфер зі стриму, в який було записано 1 розміром у integer: var Buf : array of byte; i : integer; begin SetLength(Buf,SizeOf(Integer)); Stream.Read(Buf[0],Length(buf)); Move(Buf[0],i,Length(Buf); в Buf після читання знаходиться (0,0,0,1), але таке приведення до integer дає в результаті зовсім дике число. Як буфер правильно привести до integer?

Дике число - мабуть 16777216? :о)

А записував у потік число як?

Александр. (2005-02-09 14:47) [4]

AFAIK, в INT386 сімействі процесорів порядок бітів йде зліва направо. Тобто. integer виглядатиме так 4-й байт, 3-й байт, 2-й байт, перший байт.

І якщо var i:Integer;

i:=1 то в пам'яті реально це буде виглядати, як 01, 00, 00, 00

> Олександр. (09.02.05 14:38)

У мене все нормально читається:

var Stream: TMemoryStream; I, J: Integer; Buf: array of Byte; begin I := 1; Stream := TMemoryStream.Create; try Stream.Write(I, SizeOf(I)); Stream.Position := 0; SetLength(Buf, SizeOf(Integer)); Stream.Read(Buf[0], Length(Buf)); Move(Buf[0], J, Length(Buf)); ShowMessageFmt("I = %d; J = %d", [I, J]) finally Stream.Free end end.

Александр. (2005-02-09 14:52) [7]

Точніше, стара програма писала в буфер record з трьох integer. Якщо проблема в тому, що в буфері поміняні місцями байти, боюся, як би не виявилося, що при записі такого рекорду весь буфер задом наперед виявиться.

Александр. (2005-02-09 14:54) [8]

Якщо ти по-байтно потім до цього буфера звертатимешся, то, звичайно, треба зрушувати. А так - читай одразу integer.

Але якщо зрушувати, то осьфункція. Чесно здерта з пам'ятного вихідника. Перекладала представлення числа I386 для MAC:

function Swap32(Value: Integer): Integer; var b1, b2, b3, b4: Integer;

begin b1 := Value and 255; b2 := (Value shr 8) and 255; b3 := (Value shr 16) and 255; b4 := (Value shr 24) and 255; b1 = b1 shl 24; b2 = b2 shl 16; b3 := b3 shl 8; Result := b1 або b2 або b3 або b4; end;

Александр. (2005-02-09 15:03) [10]

Александр. (2005-02-09 15:14) [12]

> Олександр. (09.02.05 14:54) [8]

for I := 0 to 3 do CopyMemory(Pointer(Cardinal(@NewValue) + I), Pointer(Cardinal(@OldValue) + 3 - I), 1)

NewValue := ((OldValue and $FF000000) shr 24) or ((OldValue and $FF0000) shr 16) or ((OldValue and $FF00) shr 8) or (OldValue and $FF)

> Олександр. (09.02.05 15:14) [12]

Як у буфері може бути лише чотири байти, якщо буфером буде змінна типу запису TRec?

Александр. (2005-02-09 15:34) [15]

До речі, я забув про команду асемблера BSWAP, що якраз підходить для цього випадку.

var I: Integer; begin I := . ; asm MOV EAX,I BSWAP EAX MOV I,EAX end . end.

Просто і зі смаком :-)

> Buf після читання знаходиться (0,0,0,1), але таке приведення > до integer дає в результаті зовсім дике число. Як > буфер

Мережевий порядок байтів. Будь-яка багатобайтова змінна передається порядку зменшення старшинства байтів у ній.

У цьому випадку змінна чотирибайтова.

Stream.Read(I, sizeof(I)); I := ntohl( I );

ntohl -NetworkToHost byte order convertion forLong

Товариш Верг, ну ви й випендрилися ж))) А чим bswap не те?

І будеш голову ламати над цим bswap скажемо у .NET

З чого ж ламати? Комент поставив і все. І що таке дотне не знаю і знати не хочу.