procedure SomeProc(l: PAnsiChar);
begin
.....
end;
var
S: string;
begin
S:='this is some text'
SomeProc(PAnsiChar(S));
end;
Как перевести из String в Pansichar?????
Как перевести из String в Pansichar?????
String в делфи - это по сути указатель на строку символов, заканчивающуюся нуль-символом, поэтому применять обычное приведение типа String в PChar не возбраняется компилятором.
Пасиба - работает :)
Хочу предостеречь юных исследователей. При подобной преобразовании строки SomeProc( PAnsiChar( MyStr ) ) строка может передаваться некорректно. У меня такая проблема возникала при передаче строки в DLL. Я использую следующий код:
Код:
Var
tmpStr: PAnsiChar;
begin
tmpStr := StrNew( PAnsiChar( MyStr ) );
SomeProc( tmpStr );
StrDispose( tmpStr );
end;
tmpStr: PAnsiChar;
begin
tmpStr := StrNew( PAnsiChar( MyStr ) );
SomeProc( tmpStr );
StrDispose( tmpStr );
end;
Я так полагаю, автор темы хотел передавать стринги в WinAPI функции - а они в этом плане безопасны для обычного typecast'а.
Моё мнение - указанный Sagittarius способ стоит использовать только в некоторых случаях, при передачи строки в DLL.
глюк возникнет, если в PAnsiChar-строку значение передаётся... для этого надо StrPCopy пользовать..... это вобщем самый первый способ для перевода строк из формата String в формат PChar, придуманный Borland... наряду с StrPas, переводящей PChar в String...
Может быть. Головой надо думать. А в остальном неправ ты, брателло.
В Дельфи есть три способа превращения AnsiString в PChar и два способа обратного превращения.
AnsiString -> PChar:
- StrCopy() - выделяет память, копирует строку, возвращает указатель выделенную память надо освобождать вручную
- PChar() - увеличивает счетчик ссылок AnsiString, возвращает указатель на буфер AnsiString, память финализируется автоматически
- Pointer() - возвращает указатель на буфер, ничего более не делая - самый небезопасный вариант
Примеров приведения к Pointer до фига в исходниках Borland - вдумчиво курим последние.
PChar -> AnsiString:
- StrNew() - аналогично StrCopy, только возвращается AnsiString; надо ли освобождать память, не знаю, скорее всего, нет
- AnsiString() - проверяет, является ли буфер указателем на строку PChar/AnsiString (в памяти они хранятся совершенно одинаково), если нет, формирует новый буфер; увеличивает счетчик ссылок, после использования память финализируется автоматически
К слову сказать, функции вроде StrPas и StrNew устарели и используются только для работы с ShortString в целях обратной совместимости. Я в Дельфи никогда их не пользовал, потому что изврат.
а по части StrNew.... она просто делает копию строки PChar и возвращает указатель на новую копию PChar, после использования надо память освобождать.... и никакого отношения к ansistring не имеет...
>..на строку PChar/AnsiString (в памяти они хранятся совершенно одинаково)...
ничего подобного..... AnsiString содержит в себе длину строки..... а PChar нет и заканчивается #0
ничего подобного..... AnsiString содержит в себе длину строки..... а PChar нет и заканчивается #0[/QUOTE]
Если бы это было так, приведение PChar() было бы невозможным. Оба типа хранят и длину, и нулевой символ в конце. Правда, для PChar хранение длины не всегда актуально - значение может быть получено и от API-функций. Но если создавать строку средствами самого Delphi - созданный AnsiString будет автоматом возвращен как PChar.
вот тебе небольшой примерчик, доказывающий, что ты не прав....
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
P: PChar;
begin
S := '2121'#0'333';
P := PChar(S);
Label1.Caption := IntToStr(Length(S));
Label2.Caption := IntToStr(Length(P));
end;
var
S: String;
P: PChar;
begin
S := '2121'#0'333';
P := PChar(S);
Label1.Caption := IntToStr(Length(S));
Label2.Caption := IntToStr(Length(P));
end;
Пример по-любому некорректен (см. ниже). Возможно, гоним мы оба. Вот измененный для консольного приложения текст:
Код:
procedure Tst;
var
S: string;
P, P2: PChar;
begin
S := '2121'#0'333';
P := PChar(S);
P2 := Pointer(S);
WriteLn(Length(S));
WriteLn(Length(P));
WriteLn(Length(P2));
end;
var
S: string;
P, P2: PChar;
begin
S := '2121'#0'333';
P := PChar(S);
P2 := Pointer(S);
WriteLn(Length(S));
WriteLn(Length(P));
WriteLn(Length(P2));
end;
Delphi 2006 сделал из него такое:
Код:
Test.dpr.14: S := '2121'#0'333';
00411C9A 8D45FC lea eax,[ebp-$04]
00411C9D BA601D4100 mov edx,$00411d60
00411CA2 E8352EFFFF call @LStrLAsg
Test.dpr.15: P := PChar(S);
00411CA7 8B45FC mov eax,[ebp-$04]
00411CAA E82532FFFF call @LStrToPChar
00411CAF 8BF0 mov esi,eax
Test.dpr.16: P2 := Pointer(S);
00411CB1 8B7DFC mov edi,[ebp-$04]
Test.dpr.17: WriteLn(Length(S));
00411CB4 8B5DFC mov ebx,[ebp-$04]
00411CB7 85DB test ebx,ebx
00411CB9 7405 jz $00411cc0
00411CBB 83EB04 sub ebx,$04
00411CBE 8B1B mov ebx,[ebx]
00411CC0 A1743B4100 mov eax,[$00413b74]
00411CC5 8BD3 mov edx,ebx
00411CC7 E8301BFFFF call @Write0Long
00411CCC E8571BFFFF call @WriteLn
00411CD1 E81210FFFF call @_IOTest
Test.dpr.18: WriteLn(Length(P));
00411CD6 8D45F8 lea eax,[ebp-$08]
00411CD9 8BD6 mov edx,esi
00411CDB E85C2FFFFF call @LStrFromPChar
00411CE0 8B5DF8 mov ebx,[ebp-$08]
00411CE3 85DB test ebx,ebx
00411CE5 7405 jz $00411cec
00411CE7 83EB04 sub ebx,$04
00411CEA 8B1B mov ebx,[ebx]
00411CEC A1743B4100 mov eax,[$00413b74]
00411CF1 8BD3 mov edx,ebx
00411CF3 E8041BFFFF call @Write0Long
00411CF8 E82B1BFFFF call @WriteLn
00411CFD E8E60FFFFF call @_IOTest
Test.dpr.19: WriteLn(Length(P2));
00411D02 8D45F4 lea eax,[ebp-$0c]
00411D05 8BD7 mov edx,edi
00411D07 E8302FFFFF call @LStrFromPChar
00411D0C 8B5DF4 mov ebx,[ebp-$0c]
00411D0F 85DB test ebx,ebx
00411D11 7405 jz $00411d18
00411D13 83EB04 sub ebx,$04
00411D16 8B1B mov ebx,[ebx]
00411D18 A1743B4100 mov eax,[$00413b74]
00411D1D 8BD3 mov edx,ebx
00411D1F E8D81AFFFF call @Write0Long
00411D24 E8FF1AFFFF call @WriteLn
00411D29 E8BA0FFFFF call @_IOTest
00411C9A 8D45FC lea eax,[ebp-$04]
00411C9D BA601D4100 mov edx,$00411d60
00411CA2 E8352EFFFF call @LStrLAsg
Test.dpr.15: P := PChar(S);
00411CA7 8B45FC mov eax,[ebp-$04]
00411CAA E82532FFFF call @LStrToPChar
00411CAF 8BF0 mov esi,eax
Test.dpr.16: P2 := Pointer(S);
00411CB1 8B7DFC mov edi,[ebp-$04]
Test.dpr.17: WriteLn(Length(S));
00411CB4 8B5DFC mov ebx,[ebp-$04]
00411CB7 85DB test ebx,ebx
00411CB9 7405 jz $00411cc0
00411CBB 83EB04 sub ebx,$04
00411CBE 8B1B mov ebx,[ebx]
00411CC0 A1743B4100 mov eax,[$00413b74]
00411CC5 8BD3 mov edx,ebx
00411CC7 E8301BFFFF call @Write0Long
00411CCC E8571BFFFF call @WriteLn
00411CD1 E81210FFFF call @_IOTest
Test.dpr.18: WriteLn(Length(P));
00411CD6 8D45F8 lea eax,[ebp-$08]
00411CD9 8BD6 mov edx,esi
00411CDB E85C2FFFFF call @LStrFromPChar
00411CE0 8B5DF8 mov ebx,[ebp-$08]
00411CE3 85DB test ebx,ebx
00411CE5 7405 jz $00411cec
00411CE7 83EB04 sub ebx,$04
00411CEA 8B1B mov ebx,[ebx]
00411CEC A1743B4100 mov eax,[$00413b74]
00411CF1 8BD3 mov edx,ebx
00411CF3 E8041BFFFF call @Write0Long
00411CF8 E82B1BFFFF call @WriteLn
00411CFD E8E60FFFFF call @_IOTest
Test.dpr.19: WriteLn(Length(P2));
00411D02 8D45F4 lea eax,[ebp-$0c]
00411D05 8BD7 mov edx,edi
00411D07 E8302FFFFF call @LStrFromPChar
00411D0C 8B5DF4 mov ebx,[ebp-$0c]
00411D0F 85DB test ebx,ebx
00411D11 7405 jz $00411d18
00411D13 83EB04 sub ebx,$04
00411D16 8B1B mov ebx,[ebx]
00411D18 A1743B4100 mov eax,[$00413b74]
00411D1D 8BD3 mov edx,ebx
00411D1F E8D81AFFFF call @Write0Long
00411D24 E8FF1AFFFF call @WriteLn
00411D29 E8BA0FFFFF call @_IOTest
Библиотечные процедуры преобразования AnsiString в PChar и обратно вызывается слишком часто, чтобы можно было говорить о корректности примера. К сожалению, у меня нет времени разбираться, в чем дело.
delphizone.ru]www.delphizone.ru там написано, как его использовать. Вот.
Про ansichar можно посмотреть в справочнике по Delphi
Спасибо, кэп. Но кажется, здесь все выяснили уже 4 года назад.