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

Вниз

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, завист все от ситуации. Иногда и такой путь приемлем


 
!sash!   (2003-04-06 04:00) [41]

Я делаю вот так :

function StrToPChar(Source : String) : PChar;
var temp : PChar;
begin
temp:=StrAlloc(MAX_PATH);
Result:=StrPCopy(temp,Source);
end;



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

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

Наверх




Память: 0.57 MB
Время: 0.013 c
3-54431
Pretender
2003-04-01 18:05
2003.04.17
почему при связке двух таблиц выдается ошибка?


4-54946
Long
2003-02-17 18:15
2003.04.17
Как с помощью WinAPI создать окно с кнопкой


1-54738
Saska
2003-04-04 10:22
2003.04.17
PChar?


1-54607
Сергей
2003-04-07 16:25
2003.04.17
DLL


3-54464
tall
2003-03-29 08:48
2003.04.17
Вычисляемые поля в SQL