Форум: "Основная";
Текущий архив: 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.008 c