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

Вниз

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

 
Saska   (2003-04-04 10:22) [0]

День добрый! Присоветуйте плиз, как корректно преобразовать String в PChar:

function NextRow(var aStr: PChar):integer;//register
var
res : string;
begin
res := "";
...
res := ...;
res[length(res)+1] := #0;
aStr := PChar(res);
end;{NextRow}

В некоторых случаях получается, что на выходе из ф-ции aStr = res+"нечто", как от этого избавиться? Заранее благодарен.


 
alexteam   (2003-04-04 10:26) [1]

хм
char_string:=pchar(my_string);


 
alexteam   (2003-04-04 10:29) [2]

и вообще кидай полный код функции а то не понятно что ты хош сделать


> Присоветуйте плиз, как корректно преобразовать String в PChar

я вро-дь бы по теме ответил


 
Saska   (2003-04-04 10:34) [3]

Проблема такая в ф-ции формируется какая-то строка, в переменной res, в некоторых случаях преобразование в PChar производится некорректно, а предоставленного кода на мой взгляд хватает...


 
alexteam   (2003-04-04 10:35) [4]

а нечто случайно не напоминает пробел :))) точнее #0 ???? а то что-то я не понял эту строчку
res[length(res)+1] := #0;
по моему и без нее будет работать


 
Palladin   (2003-04-04 10:37) [5]

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


 
Anatoly Podgoretsky   (2003-04-04 10:38) [6]

Преобразование корректное, алгоритм не корректный.
При выходе из функции, переменная res прекращается свое существование!


 
Skier   (2003-04-04 10:43) [7]

Из Help-a...

A common error when working with PChars is to store in a data structure, or return as a value, a local variable. When your routine ends, the PChar will disappear because it is simply a pointer to memory, and is not a reference counted copy of the string. For example:

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


 
Saska   (2003-04-04 11:17) [8]

Так чего ж делать то?


 
panov   (2003-04-04 11:23) [9]

Тебя же попросили код функции привести.
Того куска, который видно, недостаточно для решения.


 
Jel   (2003-04-04 11:24) [10]

Думаю вот что -


> alexteam © (04.04.03 10:26)
> хм
> char_string:=pchar(my_string);



 
alexteam   (2003-04-04 11:27) [11]

даж панов участвовал :)) радует


 
Bel   (2003-04-04 11:29) [12]

А если под PChar выделить память, а потом туда скопировать содержимое String и пусть она умирает.


 
Saska   (2003-04-04 11:30) [13]

to [panov ©]
function (aHandle: integer; var aStr: PChar): integer;//register
var
Element : IXmlElement;
res : AnsiString;
i : integer;
begin
res := "";
try
if not (Element.NodeName = MasterDoc[aHandle].DocumentElement.NodeName) then begin
for i := 0 to XMLSchema[aHandle].Count-1 do
res := res+Element.GetAttr(XMLSchema[aHandle][i], "")+Separator;
res[length(res)] := #0;
aStr := PChar(res);
except
result := -1;
ErrMsg := Errors[0];
exit;
end;
inc(XMLCursor[aHandle]);
result := 0;
end;


 
Roma   (2003-04-04 11:33) [14]

> Saska © (04.04.03 11:17)

В вызывающей программе инициализировать место под aStr, и делать в него StrCopy...

aStr - это указатель, ты ему присваиваешь указатель на начало переменной res, но res - переменная локальная, определена только в функции NextRow, по завершении функции память, под res выделенная, освобождается, и aStr, указывавший на начало res, будет указывать Билл его знает куда...
Надо в вызывающей функцию NextRow части кода объявить переменную типа PChar, проинициализировать ее, передать ее функции, в функции делай, что хочешь, а результат с помощью StrCopy помещается в aStr...


 
alexteam   (2003-04-04 11:35) [15]

res[length(res)+1] := #0;
переделано на
res[length(res)] := #0;

а интересно еще одно на кой тебе результ если в конце функции он будет всегда приравниватся к 0 ??? иль я чет не понимаю


 
Bel   (2003-04-04 11:41) [16]

> alexteam © (04.04.03 11:35)
> res[length(res)+1] := #0;
> переделано на
> res[length(res)] := #0;


А, по-моему, проще так:
res := res + #0;

> а интересно еще одно на кой тебе результ если в конце функции
> он будет всегда приравниватся к 0 ??? иль я чет не понимаю

Дык, в эксепшене после Result:=-1 стоит Exit.


 
Palladin   (2003-04-04 11:43) [17]


> alexteam © (04.04.03 11:35)

не глупите молодой человек...
где ты видишь приравнивание к #0?


 
Saska   (2003-04-04 11:46) [18]

[to Roma ©]
Была мысля такая, но заранее не известно какой длины строка будет, а выделять много места, если в итоге передается 3 символа... как-то не очень...


[to alexteam ©]
function (aHandle: integer; var aStr: PChar): integer;//register
var
Element : IXmlElement;
res : AnsiString;
i : integer;
begin
res := "";
try
if not (Element.NodeName = MasterDoc[aHandle].DocumentElement.NodeName) then begin
for i := 0 to XMLSchema[aHandle].Count-1 do
res := res+Element.GetAttr(XMLSchema[aHandle][i], "")+Separator;
res[length(res)] := #0;
aStr := PChar(res);
end;
except
result := -1;
ErrMsg := Errors[0];
exit;
end;
inc(XMLCursor[aHandle]);
result := 0;
end;


res[length(res)] := #0; - чтоб забить последний Separator, да и вообще речь не о б этом...





 
Palladin   (2003-04-04 11:48) [19]


> alexteam © (04.04.03 11:35)

приравнивание к #0 результата?


> Saska © (04.04.03 11:30)

function (aHandle: integer; var aStr: String): integer;
...
aStr:=res
...

а уже в основной программе делай чего хочешь...
зачем мучтся с pchar? для чего сделан String?


 
Bel   (2003-04-04 11:53) [20]

> Saska © (04.04.03 11:46)
> Была мысля такая, но заранее не известно какой длины строка будет, а выделять много места, если в итоге передается 3 символа... как-то не очень...

А если выделять память не в вызывающем коде, а в самой функции?...
И, всё-таки, прислушайся к совету Palladin © (04.04.03 11:48) насчёт "не мучаться с PChar".


 
Saska   (2003-04-04 11:56) [21]

> Palladin © (04.04.03 11:48)

Интерфей у ф-ции DLL такой... и с это надо принять как данность...


 
Palladin   (2003-04-04 11:58) [22]


> Saska © (04.04.03 11:56)

Uses sharemem
и в программе и в dll


 
panov   (2003-04-04 11:58) [23]

У тебя aStr какой длины может быть максимальной?


 
Anatoly Podgoretsky   (2003-04-04 11:58) [24]

Saska © (04.04.03 11:46)
Возаращай строку


 
panov   (2003-04-04 12:10) [25]

Если строка длиной меньше 128 байт, используй совершенно спокойно ShortString в DLL...


 
Тимохов   (2003-04-04 12:12) [26]

Господа, делать res[length(res)] := #0; вообще не надо.
См. help "Memorty manegment|Long strings".
Под PChar надо выделять память GetMem"ом в размере Length(Res)+1
и делать StrCopy.
GetMem(aStr, Length(Res)+1)
StrCopy(aStr, Res)


 
panov   (2003-04-04 12:17) [27]

>Тимохов (04.04.03 12:12)

Проверь свой пример именно внутри вызванной функции для aStr...


 
Palladin   (2003-04-04 12:18) [28]


> Тимохов (04.04.03 12:12)

а кто спорит то?


 
icWasya   (2003-04-04 12:21) [29]


>Saska © (04.04.03 11:17)
>Так чего ж делать то?

как делают все API-функции, когда возвращают строки
function NextRow(aStr: PChar;aLen :Integer):integer;
var
res : string;
begin
res := "";
...
res := ...;


if aLen<Length(res) then
Result:=Len
else
Result:=Length(res);
move(aStr[0],res[1],Result);

end;{NextRow}


а при вызове

var
Str:array[0..100] of char;
L:Integer;
.......
L:=NextRow(Str,SizeOf(Str));

...



 
Тимохов   (2003-04-04 12:21) [30]

> Panov. Спасибо. Так правильно

GetMem(aStr, Length(Res)+1)
StrCopy(aStr, pchar(Res))




 
panov   (2003-04-04 12:22) [31]

>Palladin © (04.04.03 12:18)
а кто спорит то?

Этот код не будет работать внутри функции, так как aStr - параметр.


 
Тимохов   (2003-04-04 12:23) [32]

> icWasya ©
Неправильно. Где #0?


 
Тимохов   (2003-04-04 12:25) [33]

>panov ©
Будет работать как я написал выше (с поправкой):
GetMem(aStr, Length(Res)+1)
StrCopy(aStr, pchar(Res))

aStr - var параметр




 
panov   (2003-04-04 12:27) [34]

>Тимохов (04.04.03 12:25)

GetMem(aStr, Length(Res)+1)

Приведет к утечкам памяти.


 
panov   (2003-04-04 12:28) [35]

Хотя сейчас специально проверю.


 
Тимохов   (2003-04-04 12:29) [36]

>panov ©
Ясный хобот, что если вызывающая сторона не будет очищать память, то будет утечка. )))))


 
Palladin   (2003-04-04 12:34) [37]


> panov © (04.04.03 12:28)

все будет нормально ибо этот параметр var
утечка? да будет, по причине Тимохов (04.04.03 12:29)


 
Тимохов   (2003-04-04 12:47) [38]

Блин да какая утечка

procedure a(var astr: pchar);
var
res: string;
begin
res := "a";
getmem(astr, length(res)+1)
strcopy(astr, pchar(res));
end;

var
p: pchar;
begin
a(p);
.... используем как-то p
freemem(p, StrLen(p)+1)
end;


 
Palladin   (2003-04-04 12:52) [39]


> Тимохов (04.04.03 12:47)

дада :) я ж не спорю я подтверждаю... что будет утечка если не освободить после отработки процедуры...

но не правильно так делать... пусть уж основная программа тогда и выделяет...


 
Тимохов   (2003-04-04 12:53) [40]

> Palladin, завист все от ситуации. Иногда и такой путь приемлем



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

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

Наверх





Память: 0.53 MB
Время: 0.009 c
3-54412
jack128
2003-03-31 18:16
2003.04.17
Проэктирование базы


7-54929
Anar
2003-02-19 23:46
2003.04.17
Звуковая карта


1-54573
AndrewK
2003-04-04 17:51
2003.04.17
Как скрыть столбец и строку в TStringGrid?


4-54953
children
2003-02-18 20:56
2003.04.17
командная строка


3-54439
Sectey
2003-04-01 10:56
2003.04.17
ClientDataSet & Index





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