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

Вниз

String   Найти похожие ветки 

 
yuliya   (2003-08-28 07:34) [0]

Как преобразовать обычную строку (String)в нультерминальную (PChar)?


 
Rouse_   (2003-08-28 07:36) [1]

Ух как смачно названо :) Даже не лень ответить ;)

Result := PChar(String);

Желаю успехов


 
yuliya   (2003-08-28 07:37) [2]

Спасибо!!!!!!!!!


 
BillyJeans   (2003-08-28 08:40) [3]

как вариант String := String + #0;


 
MBo   (2003-08-28 08:41) [4]

>BillyJeans
ни к чему - в AnsiString нуль уже есть.


 
Digitman   (2003-08-28 08:47) [5]


> yuliya


не набей только шишек советом от
> Rouse_ © (28.08.03 07:36) [1]
)

на самом деле никакого преобразования в этом случае не происходит
конструкция PChar(StringVariable) всего лишь вернет адрес буфера строковых данных (адресный указатель на буфер), которые и так уже являют собой в памяти строку символов, ограниченную нуль-терминатором.

как только динамическая структура, управляемая переменной StringVariable, перестанет существовать, строковые данные (адрес которых был ранее получен) так же "исчезнут", и полученный в Result указатель будет ссылаться уже в никуда.

пример "граблей" :

function GetStrDataPointer: PChar;
var
str: String;
begin
str := "ABCD";
Result := PChar(str);
end;

....

var
p: PChar;
l: Integer;
...

p:= GetStrDataPointer;
l := StrLen(p); // здесь с немалой вероятностью набиваем AV-шишку, ибо лок.переменная str вместе с данными, которые она хранила и на которые в предыдущем вызове ф-ции была получена ссылка, уже не существует

зачастую вот такой вариант будет более корректным, ибо после преобразования нет уже зависимости от исх.строковой переменной
var
p: PChar;
str: String;
...

str := "ABCD";
GetMem(p, Length(str) + 1); // аллокирем память под копию
try
StrCopy(p, PChar(str)); // делаем копию
str := "EFGH"; // теперь содержимое str можно произвольно менять
... здесь смело работаем с переменной p (она по прежнему указывает на строковые данные "ABCD"#0 (точнее - на только что сделанную копию с оригинала), несмотря на то что содержимое str только что изменилось)
finally
FreeMem(p); // деаллокируем память под копию
end;


 
Reindeer Moss Eater   (2003-08-28 09:12) [6]

MyPCharString:=StrNew(PChar(MyAnsiString));


 
Doctor Deejay   (2003-08-28 10:34) [7]


> MyPCharString:=StrNew(PChar(MyAnsiString));


Шаришь тему!!!!


 
han_malign   (2003-08-28 11:35) [8]

>пример "граблей" :
>function GetStrDataPointer: PChar;
>var
> str: String;
>begin
> str := "ABCD";
> Result := PChar(str);
>end;
- здесь, кстати, никаких граблей не будет - в PChar будет лежать адрес констансты "ABCD", которая живет все время работы программы - вот если заменить str := "ABCD" на SetString(str,"ABCD",4), тады ой...
За временем жизни строки источника действительно нужно следить, хотя и при использовании StrNew - нужно следить за утечками памяти (не забывать про FreeMem или StrDispose)...


 
Skier   (2003-08-28 11:38) [9]

>han_malign © (28.08.03 11:35)

> кстати, никаких граблей не будет -

Будут.


 
han_malign   (2003-08-28 11:52) [10]

>Skier © (28.08.03 11:38) [9]
- "Плавали - знаем"(с)Капитан Плавали-знаем
тогда уж вдогонку - если API-шная функция позволяет пропускать строковые(PChar) параметры, то:
s:="";
<WinApi Function>(...,PChar(s),...);

- вызовет ошибку, нужно явно указывать
<WinApi Function>(...,nil,...);
- проверено на личном опыте:
if(aAppName="")then pc:=nil else pc:=PChar(aAppName);
if(CreateProcess( pc,PChar(aCmdLine),nil,nil,false,0,nil,nil,_si ,_pi))
then Result:=NO_ERROR else Result:=GetLastError;


 
Skier   (2003-08-28 11:57) [11]

>han_malign © (28.08.03 11:52)

Хочешь поспорить с Borland-ом ? :)

Из справки :

function title(n: Integer): PChar;

var
s: string;
begin
s := Format("title - %d", [n]);
Result := PChar(s); // DON"T DO THIS
end;


 
Anatoly Podgoretsky   (2003-08-28 12:00) [12]

han_malign © (28.08.03 11:52) [10]
Не вызовет если не будет писать, нельзя говорить в отрыве от функции.


 
Reindeer Moss Eater   (2003-08-28 12:04) [13]

Количество ссылок на локальную переменную обнулится при выходе из функции. Это же очевидно.
И строка будет удалена из памяти.


 
Rouse_   (2003-08-28 12:16) [14]

> han_malign © (28.08.03 11:35) [8]

Именно в данном примере грабли есть, так как переменная Str сушествует только в пределах функции.

Желаю успехов


 
han_malign   (2003-08-28 12:32) [15]

>All
- читайте внимательнее - процитирую себя:
в PChar будет лежать адрес констансты "ABCD", которая живет все время работы программы - вот если заменить str := "ABCD" на SetString(str,"ABCD",4), тады ой...

>Anatoly Podgoretsky © (28.08.03 12:00) [12]
>>han_malign © (28.08.03 11:52) [10]
>>Не вызовет если не будет писать, нельзя говорить в отрыве от функции.
- если вы про PChar("")<>nil (что есть проверенный факт), то я сразу привел конкретный пример, где на это напоролся -
(CreateProcess(PChar(""),PChar("format C:"),...) - The system cannot find the file specified.)


 
Skier   (2003-08-28 12:33) [16]

Не убедил.


 
Reindeer Moss Eater   (2003-08-28 12:39) [17]

han_malign ©
Локальные переменные процедур "живут" не в сегменте данных.
А про константы ничего в том примере не было.


 
KSergey   (2003-08-28 13:26) [18]

[10] han_malign © (28.08.03 11:52)
[1] s:="";
<WinApi Function>(...,PChar(s),...);

[2] <WinApi Function>(...,nil,...);

Глупости. Это совершенно не эквивалентные конструкции.
В первом случае передается указатель на нулевую строку (строку, не содержащую символов), а во втором - передается нулевой указатель (фактически буквально 0), по которому вызываемая ф-ция узнает, что этот параметр ей не передан (вернее указано спец. значение - 0, т.к. в обычной ситуации процесс не пожет получить адрес буфера памяти, начинающегося в нулевом адресе)


 
KSergey   (2003-08-28 13:29) [19]

[15] han_malign © (28.08.03 12:32)
- если вы про PChar("")<>nil (что есть проверенный факт)


А в этом никто и не сомневался ;)

, то я сразу привел конкретный пример, где на это напоролся -
(CreateProcess(PChar(""),PChar("format C:"),...)


Это не напоролся называется, а вызвал ф-цию с неверными аргументами. Вот она и указала ошибку.


 
han_malign   (2003-08-28 13:41) [20]

> KSergey © (28.08.03 13:29) [19]
> Глупости. Это совершенно не эквивалентные конструкции.
- именно об этом я и говрил...(кстати, см. в самом конце этого поста)
> CreateProcess(PChar(""),PChar("format C:"),...)
> Это не напоролся называется, а вызвал ф-цию с неверными аргументами. Вот она и указала ошибку.
CreateProcess(nil,PChar("format C:"),...) - никаких ошибок

> Локальные переменные процедур "живут" не в сегменте данных.
s:="ABCD";
pc:=PChar(s);
//pc=PChar(s)=PChar("ABCD") - можете проверить, я проверял...
s:=s+"_";
//pc<>PChar(s) но!!! pc=PChar("ABCD")

>" А про константы ничего в том примере не было."
- тот пример:
>пример "граблей" :
>function GetStrDataPointer: PChar;
>var
> str: String;
>begin
> str := "ABCD";
> Result := PChar(str);
>end;

З.Ы. Я редко делаю голословные утверждения, если я говорю - значит лично проверил, и не раз.

З.З.Ы. У-у-у как все запущено, оказывается pc:=PChar(s) - это не прямое приведение типов, а LStrToPChar, а при s:="", Pointer(s)=nil, а вот PChar(s)=EmptyString - ну не западло?
function _LStrToPChar(const s: AnsiString): PChar;
const
EmptyString = "";
begin
if Pointer(s) = nil then
Result := EmptyString
else
Result := Pointer(s);
end;

- только на все выше сказанное это все равно не влияет...


 
Digitman   (2003-08-28 13:57) [21]


> han_malign ©


грабли с AV (в случае возврата существующего адреса существующей строковой константы) будут при обращении к ней в дальнейшем по записи

ибо страница-то в памяти присутствует, но доступ к ней по записи блокирован сист.загрузчиком, считавшем из PE-файла секцию (сформированную линкером) с соотв.атрибутом доступа

конечно же, тот же AV будет (с немалой долей вероятности) и в случае с str := SerString()... но связан он будет не с нарушением доступа по уровню прав, а просто с отсутствием страницы в ВАП


 
KSergey   (2003-08-28 13:59) [22]

[20] han_malign © (28.08.03 13:41)

Поразительно! Вы приводите действительно верные (видимо, действительно проверенные) утверждения, вот только совершенно с неверными предпосылками ;)

[20] han_malign © (28.08.03 13:41)
>KSergey © (28.08.03 13:29) [19]
CreateProcess(nil,PChar("format C:"),...) - никаких ошибок


Естествено. Параметры верные - ошибок нет.. Не пойму, что тут не так? можно обстоятельнее?

s:="ABCD";
pc:=PChar(s);
//pc=PChar(s)=PChar("ABCD") - можете проверить, я проверял...
s:=s+"_";
//pc<>PChar(s) но!!! pc=PChar("ABCD")


А вот это уж обман трудового населения.
Возможно, тут что-то и будет так при включенном оптимизаторе (вохзможно, дельфя догадается. что исп. одна и та же константа, но что-то сомнение меня разбирает и в этом случае.
Вот мой пример (к стати: как у вас определялась s?):

var
s, o: String;
pc: PChar;
begin
s:="ABCD";
pc:=PChar(s);
if PChar(s)=PChar("ABCD") then o := "1) 1"#13 else o := "1) 0"#13;
s:=s+"_";
if PChar(s)=PChar("ABCD") then o := o + "2) 1" else o := o + "2) 0";
ShowMessage (o);


Этот кусок выведет:

1) 0
2) 0


Как видно из текста программы - это значит, что PChar(s) никогда не будет равно PChar("ABCD"), что вообще-то логично.


 
Chlavik   (2003-09-03 01:12) [23]

А зачем юзать pChar??? помойму его надо юзать что бы с экономить памяти для передачи какойто строки куда то... (ну при условии что во премя выполнения того то не изменится источник самого PChar пускай это будет string всё равно pChar это указатель на S[0].. Что лучше передавать integer или копировать кудато array of char х. знает длины...Нас заставляет работать С Pchar WinApi и выше указаный момент... А так для работы над строками использование Pchar это штопание кода такого рода как ReAllocMem и так далее...


 
KSergey   (2003-09-03 07:24) [24]

[23] Chlavik © (03.09.03 01:12)
А зачем юзать pChar???


Его приходится юзать в случаях, когда так написаны аргументы вызываемой ф-ции (например, как было сказано, все ф-ции WinAPI) и при передаче параметров в DLL без использования ShareMem. Все.
И поправочка: pChar это указатель на S[ 1].



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

Форум: "Основная";
Текущий архив: 2003.09.15;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.022 c
4-48826
Noname_
2003-07-15 12:20
2003.09.15
Заменить заставку при загрузке Windows XP


3-48459
mOOx_
2003-08-23 14:34
2003.09.15
Общий count...


14-48737
Карлсон
2003-08-27 10:32
2003.09.15
я вернулся!


3-48445
BKGG
2003-08-24 18:41
2003.09.15
Я питаюс присоединиться к таблице Telephones, расположенную в баз


1-48614
Layner
2003-09-02 15:13
2003.09.15
меню ABOUT (о программе)





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