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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.021 c
3-78750
mike_gorb
2003-11-06 10:39
2003.11.24
Accessform


3-78794
ruslan_as
2003-11-05 13:48
2003.11.24
Как сменить в уже созданной базе InterBase пароль


3-78812
Vi0let
2003-11-05 08:29
2003.11.24
Нужно: DBComboBox отображает наименования, а возвращает код


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


1-78890
OpenGL
2003-11-13 10:19
2003.11.24
Проблема, черт возьми!!!!!!!!!!!!!!!





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский