Вниз
Скачать: CL | DM;

Указатель типа Pointer - читаем и записываем байты…   Найти похожие ветки 

 
Drex   (2005-10-24 19:50) [0]

Коллеги! Есть указатель типа Pointer на некоторую область в памяти. Как прочитать/записать байт по определенному адресу в этой памяти? Т.е. необходимо реализовать две функции типа ReadByte и WriteByte.


 
begin...end ©   (2005-10-24 19:54) [1]

var
 P: Pointer;
 B: Byte;
begin
 // Чтение
 B := PByteArray(P)[смещение_байта];
 // Запись
 PByteArray(P)[смещение_байта] := B
end.

Если значение смещение_байта может выходить из диапазона 0..32767, опишите свой тип наподобие PByteArray или просто используйте адресную арифметику.


 
umbra ©   (2005-10-24 19:57) [2]

В модуле Classes есть класс TMemoryStream, предназначенный для чего-то подобного


 
Drex   (2005-10-24 22:02) [3]

Нет господа, что-то не то. Возможно я не так объяснил…  Попробую подробнее: использую файл, отображенный в память (до 10 Мб). Получаю на него указатель Pointer и хочу работать с файлом как с одномерным массивом… Использовать что то типа result:=PByteArray(P)[adr]; на мой, сугубо субъективный взгляд – решение не очень… т.к. заранее неизвестно какого размера буду обрабатывать файл, а ограничивать себя – это не выход. Хочется какой ни будь универсальный подход… или другого выхода нет?


 
begin...end ©   (2005-10-24 22:12) [4]

> Drex   (24.10.05 22:02) [3]

Я же написал в [1] -- если не устраивает это ограничение, объявите свой тип. Ограничьте себя двумя гигабайтами, например. Разве этого недостаточно? Объявление типа ведь не занимает никакой памяти.

type
 PBArray = ^TBArray;
 TBArray = array [0..MaxInt - 1] of Byte;

и далее по тексту (см. пример в [1]).

Либо (и об этом тоже сказано в [1]) явно производите арифметические операции над указателями:

var
 P: Pointer;
 B: Byte;
begin
 // запись байта
 PByte(Cardinal(P) + смещение_байта)^ := B;
 // чтение байта
 B := PByte(Cardinal(P) + смещение_байта)^
end.


 
Игорь Шевченко ©   (2005-10-24 22:51) [5]

begin...end ©   (24.10.05 22:12) [4]


> Объявление типа ведь не занимает никакой памяти.


Давай объявим так:

THugeByteArray = array[0..$7FFFFFFF] of Byte;
PHugeByteArray = ^THugeByteArray;

и попробуем откомпилировать.

Удивимся.


 
Prohodil Mimo ©   (2005-10-24 23:28) [6]

begin...end ©   (24.10.05 22:12) [4]

то же самое, но размер чутка поменьше задать, что бы не превышать дозволенных 2гига.


 
palva ©   (2005-10-25 00:14) [7]

> то же самое, но размер чутка поменьше задать
Ну да, если процитировать код begin...end, то
TBArray = array [0..MaxInt - 1] of Byte;
и компиляция пройдет.


 
Alex Konshin ©   (2005-10-25 03:07) [8]

var
P: Pointer;
B: Byte;
begin
// запись байта
PByte(Cardinal(P) + смещение_байта)^ := B;
// чтение байта
B := PByte(Cardinal(P) + смещение_байта)^
end.


PByte(PChar(P)+смещение_байта) is better.


 
begin...end ©   (2005-10-25 08:19) [9]

> Игорь Шевченко ©   (24.10.05 22:51) [5]

Вы это к чему?
Ваш код не компилируется, мой код компилируется. Это связано с ограничением размера типа в 2 ГБ.

> Удивимся.

Честно говоря, не нашёл причин для удивления.


 
Игорь Шевченко ©   (2005-10-25 10:10) [10]

begin...end ©   (25.10.05 08:19) [9]


> Вы это к чему?
> Ваш код не компилируется, мой код компилируется. Это связано
> с ограничением размера типа в 2 ГБ.


Вот и я к этому. К тому, что объявление типа места не занимает :) Однако, ограничение на размер все-таки есть.



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

Скачать: CL | DM;



Память: 0.47 MB
Время: 0.036 c
2-1130285196
snowkam
2005-10-26 04:06
2005.11.13
как исключить ошибку


11-1111437864
thaddy
2005-03-21 23:44
2005.11.13
for stals


2-1130348210
SamProf
2005-10-26 21:36
2005.11.13
Как получить адрес из суммы двух адресов?


14-1129805568
ZeroDivide
2005-10-20 14:52
2005.11.13
Новые драйверы для ATI, рядовое событие, если бы не одно НО


1-1129690270
Александр Слоб.
2005-10-19 06:51
2005.11.13
Динамический массив: ошибка компилятора?




   Наверх