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

Вниз

Поменять указатель на первый символ строки.   Найти похожие ветки 

 
Yuri Btr ©   (2003-11-11 17:10) [0]

Ув. мастера, у меня есть указатель (Data: PByte) на первый байт какой-то области памяти (Size - размер области) в моей программе, скажите, как можно обратиться к ней (к области) как к строке. Можно ли в процедуре явно указать, что первый символ строки располагается по адресу Data^ , а её размер равен размеру интересующей меня области. Вот таким образом - не получается. Возможно ли это в принципе?

@SourceString[1]:=Data^;
SetLength(SourceString,Size);

SourceString это локальная переменная некой процедуры.
Заранее спасибо.


 
Reindeer Moss Eater ©   (2003-11-11 17:15) [1]

PChar(Data)

Если в конце есть #0


 
Anatoly Podgoretsky ©   (2003-11-11 17:15) [2]

PChar


 
mOOx_ ©   (2003-11-11 17:17) [3]

А вот так
PChar(Data);


 
mOOx_ ©   (2003-11-11 17:19) [4]

Инет тормозит :)


 
Yuri Btr ©   (2003-11-11 17:20) [5]

Сорри, конечно же так не проходит.

SetLength(SourceString,Size);
@SourceString[1]:=Data;
--------------------

PChar(Data) не подходит - в данной области встречается #0
посему String(PChar(Data)), сработает до первого #0
а вся остальная область будет недоступна ?


 
Reindeer Moss Eater ©   (2003-11-11 17:20) [6]

Если нет нуля в конце блока памяти:

var pStr:PChar;
begin
pStr:=StrAlloc(Size);
StrLCopy(pStr,PChar(Data),Size);
end;


 
Reindeer Moss Eater ©   (2003-11-11 17:22) [7]

Если внутри блока есть нули, то Move.
Но с полученной "строкой" все равно нельзя будет работать как со строкой


 
Yuri Btr ©   (2003-11-11 17:25) [8]

to Reindeer Moss Eater ©
понимаете, эта область представляет собой отображаемый в память файл. А он может быть очень большим...
Раньше я делал копию области в строку
var
p1,p2:pointer;
.....
SetLength(SourceString,Size);
p1:=Data;
p2:=@SourceString[1];
CopyMemory(p2,p1,Length(SourceString));

но скорость не устраивала, к тому же зачем копировать данные в новую переменную SourceString, если они уже есть в программе и начинаются с Data, вот я и подумал что можно ли расположить строку в памяти с указателя Data.


 
Reindeer Moss Eater ©   (2003-11-11 17:27) [9]

тебе же русским языком сказали, что можно.
Но работать с этим куском памяти как со строкой - забудь


 
Yuri Btr ©   (2003-11-11 17:29) [10]

to Reindeer Moss Eater ©
Пока вам писал, вы мне уже ответили :)
Reindeer Moss Eater © (11.11.03 17:22) [7]

Мне и не надо ничего удалять, или изменять - только доступ к символам. Спасибо.


 
Digitman ©   (2003-11-11 17:30) [11]

лучше не делай этого

по двум соображениям

1. формат внутренней упр.структуры, которую определяет переменная SourceString (фактически это - указатель на структуру), может меняться от версии к версии

2. указав тем или иным образом некорректный (с т.з. прав доступа к странице) адрес, по которому находятся нужные строковые данные, ты рискуешь как минимум получить EInvalidPointer или AV, когда структура будет автоматически уничтожаться и будет произведена попытка освобождения блока памяти, на который "смотрит" подмененный тобой указатель


 
Yuri Btr ©   (2003-11-11 17:37) [12]

to Digitman ©
т.е. для быстрого доступа к области памяти лучше зная начальный указатель (Data) и нужное смещение символа (напр. Offset)- вручную обращаться по сумме Data+Offset, пока не достигнем Data+Size ?
и лучше ничего нет ...


 
Digitman ©   (2003-11-11 17:38) [13]


> Yuri Btr


Как я понял, фактически ты ведешь речь НЕ о подмене указателя, а о явном преобразовании типа перед операцией присвоения полученного значения некоей строк.переменной. А это две разные разницы.

SetLength(SourceString,Size); // сначала резервируем память в Size байт
strlcopy(PChar(SourceString), pchar(Data), Size); // и лишь теперь копируем туда Size байт из источника !!


 
Digitman ©   (2003-11-11 17:40) [14]


> для быстрого доступа к области памяти


для этого вообще нужно стараться избегать везде где это возможно использования типа String


 
Yuri Btr ©   (2003-11-11 17:45) [15]

to Digitman ©
Ваш пример копирует лишь до первого символа #0.
Вернее он копирует всю Size, но после обращения к String, всё что после первого попавшегося символа #0 становится тоже #0.
Это "ограничение" Pchar. Но что делать, если нужно работать и с такими символами, аот я и подумал о String.


 
han_malign ©   (2003-11-11 17:50) [16]

> по сумме Data+Offset, пока не достигнем Data+Size
- по моему, должно проходить - PChar(Data)[Offset] (естественно с проверкой Offset<Size)
ch:=PChar(Data)+Offset ^; - проходит точно...

> SetLength(SourceString,Size); // сначала резервируем память в Size байт
> strlcopy(PChar(SourceString), pchar(Data), Size); // и лишь теперь копируем туда Size байт из источника !!
- в System давно уже есть SetString(DestString,PChar(Data),Size);


 
Digitman ©   (2003-11-11 17:50) [17]


> Ваш пример копирует лишь до первого символа #0.


тогда вместо strlcopy() используй Move()

последняя копирует безо всяких проверок


 
Yuri Btr ©   (2003-11-11 17:55) [18]

to Digitman ©
А это я уже делал посмотрите пожалуйста..
Yuri Btr © (11.11.03 17:25) [8]

to han_malign ©
SetString - ?
посмотрю...

Но проблему это не решает.. посмотрите выше пост № 8


 
Digitman ©   (2003-11-11 18:03) [19]


> Yuri Btr


я не понимаю, какие такие "проблемы")

собственно копирование что в [8] что в [17] выполняется корректно и без прооблем, разве что в [8] зачем-то доп.переменные введены

другой вопрос, что т.н. "проблемы" встают после копирования в полный рост, ибо в стр.данных, которые ты скопировал, содержат нуль-терминаторы, и они рано или поздно дадут о себе знать при обращении к разного рода ф-циям, оперирующими переменными типа String.

ты лучше вот что поясни - ну скопировал ты, предположим, теперь строковая переменная содержит вот такие "хитрые" стр.данные, что дальше плпнируешь с этой переменной делать ? как использовать ?


 
han_malign ©   (2003-11-11 18:11) [20]

Дык, ты объясни - зачем тебе именно строка.
Если для поэлементного обращения - PChar(Data)[Offset],
если s:=Copy(Data,i,cnt) - то SetString(s,PChar(Data)+i,cnt),
а вот Delete, Pos и конкатенация - ручками...

> они рано или поздно дадут о себе знать при обращении к разного рода ф-циям, оперирующими переменными типа String
- неправда ваша, как раз для String, символ #0, такой же симовл как и все остальные, проблемы начинаются только при преобразовании к ASCIIZ-строке и обратно.


 
Digitman ©   (2003-11-11 18:33) [21]


> han_malign


вот это, по-твоему, неправда ?))

const str: PChar = "ABC" #0"DEF"; // 7 байт (+1 на финальный терминатор)

procedure TForm1.Button2Click(Sender: TObject);
var
data: PByte;
ds: String;
begin
data := Pointer(str);
setlength(ds, 7);
copymemory(PChar(ds), data, 7);
showmessage(inttostr(length(ds))); // что видим ? 7-ку видим, иного и не ожидалось
showmessage(ds); // а здесь что видим ? правильно, "ABC" видим !
end;

и где здесь эски-преобразование ? даже неявного нет в коде, вставленном компилятором !

в конечном итоге будет вызвана ExtTextOut(), которая оперирует указателем на нуль-терминированную строку


 
Yuri Btr ©   (2003-11-11 18:41) [22]

to han_malign ©
to Digitman ©
только для поиска вхождений искомой строки в отображаемый файл, и получения смещений.

т.е. строка может быть и read-only.
Просто я не "вижу" смысла в копировании участка памяти, если он уже имеется в программе.Вот поэтому и предложил подменить указатели. Конечно я мог и ошибиться, предположив такой "хитрый" ход


 
Digitman ©   (2003-11-12 08:10) [23]


> только для поиска вхождений искомой строки в отображаемый
> файл, и получения смещений.


все равно непонятно, заче для этого string-тип понадобился


 
Reindeer Moss Eater ©   (2003-11-12 11:49) [24]

Видимо кроме Pos ничего не знает



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

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

Наверх




Память: 0.53 MB
Время: 0.015 c
3-78797
a_andru
2003-11-05 19:08
2003.11.24
Оле Оракл два запроса


11-78866
dreddd
2003-03-05 21:43
2003.11.24
про форму и UDP


3-78809
Tumcoat
2003-11-05 03:30
2003.11.24
Проблема с бегунком DBGrid-а в dBase


1-78882
dimm
2003-11-13 11:48
2003.11.24
Уважаемые, как забить в поле ввода определённой формы


1-78925
Dred
2003-11-12 01:39
2003.11.24
Структура данных