Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi D2010: Problem bei Typkonvertierung String => PAnsiChar (https://www.delphipraxis.net/150536-d2010-problem-bei-typkonvertierung-string-%3D-pansichar.html)

Angel4585 20. Apr 2010 08:45


D2010: Problem bei Typkonvertierung String => PAnsiChar
 
Hallo,

ich habe gerade ne Stunde damit verbracht einen Fehler in meiner Software zu finden.
Es hat sich herausgestellt, das es ein Problem in der Typenkonvertierung von String nach PAnsiChar gibt.

Ich hab das mal ein paar Testzeilen gemacht:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
LString : string;
LAnsiString : AnsiString;
LPAnsiChar1,LPAnsiChar2,LPAnsiChar3,LPAnsiChar4,LPAnsiChar5 : PAnsiChar;
begin
LString:='C:\MeinOrdner\MeinUnterOrdner\MeineDatei.Endung';
LAnsiString:=LString;
LPAnsiChar1:=PAnsiChar(LString);
LPAnsiChar2:=PAnsiChar(ExtractFilePath(LString));
LPAnsiChar3:=PAnsiChar(LString+' -Param1');
LPAnsiChar4:=PAnsiChar(LAnsiString+' -Param1');
LPAnsiChar5:=PAnsiChar(LAnsiString+' -Param1 '+LString);
ShowMessage('LPAnsiChar1='+LPAnsiChar1);
ShowMessage('LPAnsiChar2='+LPAnsiChar2);
ShowMessage('LPAnsiChar3='+LPAnsiChar3);
ShowMessage('LPAnsiChar4='+LPAnsiChar4);
ShowMessage('LPAnsiChar5='+LPAnsiChar5);
end;
LString hat bei der Ausgabe den angegebenen Pfad.
LPAnsiChar1-3 haben nur "C".
LPAnsiChar hat den vollen Pfad + dem Parameter.
LPAnsiChar5 hat wieder nur "C".

Jetzt ist mir natürlich bewusst, dass String ein WideString ist, aber warum bringt denn der Compiler keine Warnung-/Fehler-Meldung, wenn diese Konvertierung zu Problemen führt?

mkinzler 20. Apr 2010 08:59

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
Deklariere LString einfach als AnsiString.

Angel4585 20. Apr 2010 09:04

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
LPAnsiChar2 hat dann trotzdem nur C, weil die Methode String als Ergebnis liefert. Ne entsprechende Ansimethode wies es die ja bei anderen Methoden öfters gibt, gibt es hier nicht.
Ich kann das natürlich mit LPAnsiChar2:=PAnsiChar(AnsiString(ExtractFilePath( LString))); hinbekommen, aber schön ist das nicht.

himitsu 20. Apr 2010 09:35

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
LAnsiString: Bei Zuweisung von String/UnicodeString an AnsiString nimmt Delphi automatisch eine Umwandlung/Konvertierung vor.
Bei Pountertypen ist sowas nicht mautomatisch möglich.


Bei LPAnsiChar1 bis LPAnsiChar3 und vielleicht noch LPAnsiChar5 sollte Delphi bezüglich der falschen Typkonvertierung (UnicodeString nach PAnsiChar) meckern.
Und wenn man dieses ignoriert, dann soll man sich auch nicht über ein fehlerhaftes Ergebnis beschweren.

LPAnsiChar4 ist das Einzige, welches lokal zwar geht, aber global nicht, da das Zwischenergebnis der Stringverknüpfung ( + ) nach Beenden der Prozedur freigegeben wird.

Angel4585 20. Apr 2010 10:03

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
Zitat:

Zitat von himitsu
Bei LPAnsiChar1 bis LPAnsiChar3 und vielleicht noch LPAnsiChar5 sollte Delphi bezüglich der falschen Typkonvertierung (UnicodeString nach PAnsiChar) meckern.
Und wenn man dieses ignoriert, dann soll man sich auch nicht über ein fehlerhaftes Ergebnis beschweren.

Ich ignoriere nix, da kommt nirgends ne Meldung, keine Warnung, garnichts. an anderen Stellen habe ich Warnung bzgl implizierter Stringumwandlung, aber an diesen Stellen kommt definitiv nix. Du hast auch Delphi 2010 Professional, genau wie ich. Bekommst du Warnungen oder so?

himitsu 20. Apr 2010 10:16

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
Delphi-Quellcode:
{31} LString:='C:\MeinOrdner\MeinUnterOrdner\MeineDatei.Endung';
{32} LAnsiString:=LString;
{33} LPAnsiChar1:=PAnsiChar(LString);
{34} LPAnsiChar2:=PAnsiChar(ExtractFilePath(LString));
{35} LPAnsiChar3:=PAnsiChar(LString+' -Param1');
{36} LPAnsiChar4:=PAnsiChar(LAnsiString+' -Param1');
{37} LPAnsiChar5:=PAnsiChar(LAnsiString+' -Param1 '+LString);
{38} ShowMessage('LPAnsiChar1='+LPAnsiChar1);
{39} ShowMessage('LPAnsiChar2='+LPAnsiChar2);
{40} ShowMessage('LPAnsiChar3='+LPAnsiChar3);
{41} ShowMessage('LPAnsiChar4='+LPAnsiChar4);
{42} ShowMessage('LPAnsiChar5='+LPAnsiChar5);
Dann solltest du wohl besser mal dein Delphi überprüfen. :gruebel:
Zitat:

[DCC Warnung] Unit2.pas(32): W1058 Implizite String-Umwandlung mit potenziellem Datenverlust von 'string' zu 'AnsiString'
[DCC Warnung] Unit2.pas(33): W1044 Bedenkliche Typumwandlung von string in PAnsiChar
[DCC Warnung] Unit2.pas(34): W1044 Bedenkliche Typumwandlung von string in PAnsiChar
[DCC Warnung] Unit2.pas(35): W1044 Bedenkliche Typumwandlung von string in PAnsiChar
[DCC Warnung] Unit2.pas(37): W1057 Implizite String-Umwandlung von 'AnsiString' zu 'string'
[DCC Warnung] Unit2.pas(37): W1044 Bedenkliche Typumwandlung von string in PAnsiChar

Angel4585 20. Apr 2010 10:25

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
:shock: Na dann schau ich mal

gmc616 20. Apr 2010 16:42

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
Hatte grad einen ähnlichen Fall.

Bei mir hat das geholfen:
Delphi-Quellcode:
LPAnsiChar1:=PAnsiChar(AnsiString(LString));
Macht ja irgendwie auch Sinn. :stupid:

himitsu 20. Apr 2010 17:00

Re: D2010: Problem bei Typkonvertierung String => PAnsiCh
 
Zitat:

Zitat von gmc616
Bei mir hat das geholfen:
Delphi-Quellcode:
LPAnsiChar1:=PAnsiChar(AnsiString(LString));

Theoretisch ja, denn hier wandelst du den UnicodeString in einen AnsiString und erzeugst davon einen Pointer.

Praktisch ist es aber unpraktisch, da man so keine richtige Kontrolle über die temporär erzeugte delphi-interne AnsiString-Variable hat.
Heißt, du hast keine wirkliche Kontrolle darüber, wann Delphi den AnsiString freigibt und wann somit der Pointer darauf ungültig wird.

Sicherer wäre also Folgendes, denn hier kannst du bestimmen wann MyTempStr freigegeben wird.
Delphi-Quellcode:
var MyTempStr: AnsiString;

MyTempStr := AnsiString(LString);
LPAnsiChar1 := PAnsiChar(MyTempStr);
Selbiges gilt für Alles, wo man keine Konrolle über das Ergebnis besitzt.
Delphi-Quellcode:
var MyTempStr: AnsiString;

MyTempStr := LString+' -Param1';
LPAnsiChar3 := PAnsiChar(MyTempStr);


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz