Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Функция копирования PChar в string [D6, D7, Win2k, WinXP]


Страницы:   1 2

MetalFan ©   (2006-10-16 17:57:00) 

что необходимо:
1) копировать содержимое string в Pchar
2) выделять/перевыделять память под PChar
3) очищать PChar, если длинна string = 0;

вот написана такая функция
function SetPChar( var APChar: PChar; const ACopyString: string): PChar;
 var
   lLenStr: Integer;
 begin
   Result := nil;
   lLenStr := Length(ACopyString);
   if (APChar = nil) and ( lLenStr= 0) then Exit;
   if lLenStr = 0 then
   begin
      FreeMem( APChar{, 0});
      APChar := nil;
   end
   else
   begin
     ReallocMem( APChar, lLenStr + 1);
     //Result := StrLCopy(APChar, PChar(ACopyString), lLenStr);
     CopyMemory( APChar, @ACopyString[1], lLenStr);
     APChar[lLenStr] := #0;
   end;
   Result := APChar;
 end;

оцените ее правильность %) что-то никак не соображу, есть ли тут косяки...


Anatoly Podgoretsky   (2006-10-17 10:05:00) [1]


> А действительно, для чего понадобилось использовать и то
> и другое??

В Дельфи PChar использовать не требуется. String полностью совместим с PChar

> только для Win-API ф-ий, и то, чаще всего, можно не явно
> использовать.

И там не требуется, а если функция возращает PChar, то никому не запрещено сделать S := PChar


icWasya   (2006-10-17 09:51:00) [2]

>>зачем вообще упали этот PChar в Делфи
А действительно, для чего понадобилось использовать и то и другое??


Eraser   (2006-10-16 23:43:00) [3]

в догонку:
зачем вообще упали этот PChar в Делфи... не зря есть намного более удобный типа - string. С ним и надо работать, а PChar - только для Win-API ф-ий, и то, чаще всего, можно не явно использовать.


MetalFan   (2006-10-16 21:43:00) [4]


> Для этого обычно используют TStringList.

есть необходимость использовать TList)
но спасибо за совет ;)


Leonid Troyanovsky   (2006-10-16 20:20:00) [5]


> MetalFan ©   (16.10.06 20:12) [22]

> вне функции имеем TList, в котором хранятся таким образом
> выделяемые PChar'ы...


Для этого обычно используют TStringList.
Если, вдруг, потребуются PChar делают PChar(Strings[i])

> function SetPChar( var APChar: PChar; const ACopyString:

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

--
Regards, LVT.


Ketmar   (2006-10-16 20:13:00) [6]

>[21] MetalFan(c) 16-Oct-2006, 20:10
> if lLenStr > 0 then inc(lLenStr);
угу. вот это-то я и забыл. %-) похмеляццо надо чаще. %-)


MetalFan   (2006-10-16 20:12:00) [7]

Leonid Troyanovsky ©   (16.10.06 20:10) [20]
вне функции имеем TList, в котором хранятся таким образом выделяемые PChar'ы...


MetalFan   (2006-10-16 20:10:00) [8]

а, ну да, вот что в итоге у меня получилось:
function SetPChar( var APChar: PChar; const ACopyString: string): PChar;
 var
  lLenStr: Integer;
 begin
  lLenStr := Length(aCopyString);
  if lLenStr > 0 then
    inc(lLenStr);
  ReallocMem(aPChar, lLenStr);
  if lLenStr > 0 then
   Move(aCopyString[1], aPChar^, lLenStr);
  result := aPChar;
end;


Leonid Troyanovsky   (2006-10-16 20:10:00) [9]


> MetalFan ©   (16.10.06 19:04) [7]

> string  в pchar, чтобы дальнейшая судьба string'а никак
> не влияла на резульирующий pchar.


Обычно в этих случаях поступают так:

Допустим, что p - указатель на буфер достаточного размера,
скажем, a: array [0..MAX_BUF] of Char

Тогда нам достаточно сделать StrPCopy(a, s).
Хотя, конечно, предпочтительней StrPLCopy.

Если такого массива нет, то для начала, распределим
буфер (StrAlloc, GetMem), как минимум Length(s)+1 байт.
Ну, а далее - StrP(L)Copy.

Когда в оной строке более нет нужды делаем StrDispose/FreeMem.

Больше, собс-но, ничего не нужно.
Хотя, конечно, вышеописанное легко сделать и с помощью Move.

Главное, что нет никакой необходимости писать некую функцию,
которая объединит распределение буфера и копирование в него,
бо от этого возникает одна лишь путаница.

--
Regards, LVT.


MetalFan   (2006-10-16 20:09:00) [10]

2 Ketmar ©  [17,18]
да ладно, ерунда)
спасибо за помощь в оптимизации кода!


Ketmar   (2006-10-16 20:04:00) [11]

зыж не зря я свои проекты начинаю писать только часа через 4 после того, как проснусь. %-)


Ketmar   (2006-10-16 20:03:00) [12]

ай. ай. ай. каюсь. посыпаю тыкву пеплом. больше не буду спросонья код давать! таки налажал. код прошу считать недействительным. %-)


MetalFan   (2006-10-16 20:03:00) [13]

с учетом след.изменений валиться все перестало %)
var
  lLenStr: Integer;
 begin
  lLenStr := Length(aCopyString);

  if lLenStr > 0 then
  begin
   ReallocMem(aPChar, lLenStr+1);
   Move(aCopyString[1], aPChar^, lLenStr+1);
  end
  else
    ReallocMem(aPChar, 0);
  result := aPChar;


Palladin   (2006-10-16 19:51:00) [14]


> [13] Ketmar ©

Это как? Резервируешь Length, а Move делаешь на Length+1 ? ай ай ай... :)


> всё работает.

Ага, "по встречке тоже можно ехать" (с) :)


Loginov Dmitry   (2006-10-16 19:51:00) [15]

Ketmar ©   (16.10.06 19:33) [13]
ReallocMem(aPChar, lLenStr);


Единичку к lLenStr было бы неплохо приплюсовать, имхо


Ketmar   (2006-10-16 19:33:00) [16]

>[12] MetalFan(c) 16-Oct-2006, 19:30
>вместо этого [0] проэкт просто "умирает" с AV сразу после
>вызова...
ищи у себя баг.

{$APPTYPE CONSOLE}

function SetPChar (var aPChar: PChar; const aCopyString: string): PChar;
var
 lLenStr: Integer;
begin
 lLenStr := Length(aCopyString);
 ReallocMem(aPChar, lLenStr);
 if lLenStr > 0 then Move(aCopyString[1], aPChar^, lLenStr+1);
 result := aPChar;
end;

var
 s: string;
 p: PChar;
begin
 p := nil; s := 'test';
 SetPChar(p, s); WriteLn('"', p, '"');
 s := 't1';
 SetPChar(p, s); WriteLn('"', p, '"');
 s := '';
 SetPChar(p, s); if p > nil then WriteLn('!');
end.


всё работает.


MetalFan   (2006-10-16 19:30:00) [17]

с этим
> Ketmar ©   (16.10.06 19:09) [8]
вместо этого [0] проэкт просто "умирает" с AV сразу после вызова...


Ketmar   (2006-10-16 19:13:00) [18]

натурально, справедливо только для {$H+}.


Ketmar   (2006-10-16 19:12:00) [19]

>[9] MetalFan(c) 16-Oct-2006, 19:12
>а #0 в конце разве будет? или в string'е тоже #0 в кноце "
>висит"?
rtfm.


MetalFan   (2006-10-16 19:12:00) [20]


> Ketmar ©   (16.10.06 19:09) [8]

а #0 в конце разве будет? или в string'е тоже #0 в кноце "висит"?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо