Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];

Вниз

Как правильно массив байт привести к 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.034 c
1-1108626509
Gost
2005-02-17 10:48
2005.03.06
Что за тип - Currency?


1-1109098758
Knoxville
2005-02-22 21:59
2005.03.06
Как закодировать данные?


1-1108899432
physic
2005-02-20 14:37
2005.03.06
TChart не строит ординату больше 1817


14-1108716632
syte_ser78
2005-02-18 11:50
2005.03.06
уменьшение значения переменной в цикле


1-1108642302
viola
2005-02-17 15:11
2005.03.06
Первая производная





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский