Як правильно масив байт привести до 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
З чого ж ламати? Комент поставив і все. І що таке дотне не знаю і знати не хочу.