Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.06;
Скачать: CL | DM;

Вниз

Как правильно массив байт привести к integer?   Найти похожие ветки 

 
Aleksandr.   (2005-02-09 14:38) [0]

Читаю буфер из стрима, в который было записано 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?


 
Ega23 ©   (2005-02-09 14:40) [1]

Дикое число - поди 16777216?  :о)


 
Alexander Panov ©   (2005-02-09 14:42) [2]

А записывал в поток число как?


 
КаПиБаРа ©   (2005-02-09 14:46) [3]

Stream.Read(I,SizeOf(Integer));


 
Aleksandr.   (2005-02-09 14:47) [4]

Ega23 ©  : ага. Оно самое.

Alexander Panov ©  :
В поток писалось Write(I,SizeOf(i));
Проблема началась с того, что потребовалось обеспечить совместимость новой и старой программы в работе с потоком на сокете. При этом новая однозначно в поток пишет integer и останавливается, а старая пишет туда большой и толстый массив байт. Поэтому для совместимости читаю буфер размером с integer и по его числу определяю, какой версией была сделана запись.


 
Ega23 ©   (2005-02-09 14:49) [5]

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

И если
var
i:Integer;

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


 
begin...end ©   (2005-02-09 14:52) [6]

> Aleksandr.   (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.


 
Aleksandr.   (2005-02-09 14:52) [7]

Точнее, старая программа писала в буфер record из трех integer. Если проблема в том, что в буфере поменяны местами байты, боюсь, как бы не оказалось, что при записи такого рекорда там весь буфер задом наперед окажется.


 
Aleksandr.   (2005-02-09 14:54) [8]

Ega23 © :
ох, эти операции сдвига, млин... туго у меня с ними. Как развернуть i в нужную сторону после приведения?


 
Ega23 ©   (2005-02-09 14:59) [9]

Если ты по-байтно потом к этому буферу будешь обращаться, то, конечно, сдвигать надо. А так - читай сразу 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 or b2 or b3 or b4;
end;



 
Aleksandr.   (2005-02-09 15:03) [10]

Ega23 © :
Епрст. Как все сложно-то. Спасибо! Только еще вопрос: а как будет располагаться в буфере такое:

type
 TRec = record
   i1 : integer;
   i2 : integer;
   i3 : integer;
 end;
var
 R : TRec;
begin
 Stream.Write(R,SizeOf(r))

В смысле, i1, i2, i3 там будут последовательно, но с перевернутыми байтами внутри числа, или еще и сам порядок полей будет i3, i2, i1?


 
Ega23 ©   (2005-02-09 15:06) [11]

Если ты пишешь данные в буфер по-рекордно, то и читай их оттуда по-рекордно, тогда никаких проблем не будет.
А вот если их оттуда по-байтово читать, то можно на грабли нарваться...


 
Aleksandr.   (2005-02-09 15:14) [12]

Ega23 ©  :
Ну не могу я их порекордно читать... Если в буфере окажется только четыре байта, а я буду ждать 12 байт, для соединения это в конечном итоге закончится таймаутом...


 
begin...end ©   (2005-02-09 15:17) [13]

> Aleksandr.   (09.02.05 14:54) [8]

1.

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

2.

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


 
begin...end ©   (2005-02-09 15:23) [14]

> Aleksandr.   (09.02.05 15:14) [12]

Как в буфере может оказаться только четыре байта, если буфером будет переменная типа записи TRec?


 
Aleksandr.   (2005-02-09 15:34) [15]

begin...end ©  :
Я же объяснил, что в поток могут записывать две программы - старая версия пишет integer, а новая - только integer, в то время как приемник для чтения потока один общий. Спасибо за код.


 
begin...end ©   (2005-02-09 18:56) [16]

Кстати, я забыл про команду ассемблера BSWAP, как раз подходящую для этого случая.

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


Простенько и со вкусом :-)


 
SammIk ©   (2005-02-20 21:58) [17]

Вот так-так


 
Verg ©   (2005-02-20 22:07) [18]


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


Сетевой порядок байтов. Любая многобайтовая переменная передается в порядке уменьшения старшинства байтов в ней.

В данном случае переменная четырехбайтовая.

uses Winsock;

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


ntohl - Network To Host byte order convertion for Long


 
SammIk ©   (2005-02-20 22:24) [19]

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


 
Anatoly Podgoretsky ©   (2005-02-20 23:20) [20]

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


 
SammIk ©   (2005-02-21 07:04) [21]

С чегоже ломать-то?
Комент поставил и усе.
И что такое дотнет не знаю и знать не хочу.



Страницы: 1 вся ветка

Текущий архив: 2005.03.06;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.027 c
14-1108483270
Dimedrol
2005-02-15 19:01
2005.03.06
DVD болванки eProformance


3-1107334563
saNat
2005-02-02 11:56
2005.03.06
Кавычки в запросе


1-1109018851
Object
2005-02-21 23:47
2005.03.06
Создание функций Undo и Redo.


14-1108127922
AlexG
2005-02-11 16:18
2005.03.06
Получение списка нажатых чекбоксов на HTML странице (HTML)


3-1107230737
YK
2005-02-01 07:05
2005.03.06
Как организовать откат транзакции?