Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   String und PChar frage (https://www.delphipraxis.net/211249-string-und-pchar-frage.html)

KodeZwerg 21. Aug 2022 09:51

String und PChar frage
 
Ich war auf der Suche nach einem Dialog der sich selbst schließen kann und bin hier im Forum auf das gestoßen:
Delphi-Quellcode:
const
  MB_TIMEDOUT = 32000;

function MessageBoxTimeOut(hWnd: HWND; lpText: PChar; lpCaption: PChar; uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): Integer; stdcall; external user32 name {$IFDEF UNICODE}'MessageBoxTimeoutW'{$ELSE}'MessageBoxTimeoutA'{$ENDIF};
function MessageBoxTimeOutA(hWnd: HWND; lpText: PAnsiChar; lpCaption: PAnsiChar; uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): Integer; stdcall; external user32 name 'MessageBoxTimeoutA';
function MessageBoxTimeOutW(hWnd: HWND; lpText: PWideChar; lpCaption: PWideChar; uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): Integer; stdcall; external user32 name 'MessageBoxTimeoutW';
ein paar themen weiter hat himitsu das daraus gemacht:
Zitat:

Zitat von himitsu (Beitrag 1160918)
Delphi-Quellcode:
const LibLang = {$IFDEF UNICODE}'W'{$ELSE}'A'{$ENDIF}; // wenn man das öfters mal braucht
function MessageBoxTimeOut(OwnerWindow: HWND; const Text, Caption: string;
  MType: LongWord; LanguageID: Word; Milliseconds: LongWord): Integer; stdcall;
  external user32 name 'MessageBoxTimeout' + LibLang;
function MessageBoxTimeOutA(OwnerWindow: HWND; const Text, Caption: AnsiString;
  MType: LongWord; LanguageID: Word; Milliseconds: LongWord): Integer; stdcall;
  external user32;
function MessageBoxTimeOutW(OwnerWindow: HWND; const Text, Caption: {$IFDEF UNICODE}UnicodeString{$ELSE}WideString{$ENDIF};
  MType: LongWord; LanguageID: Word; Milliseconds: LongWord): Integer; stdcall;
  external user32;

Ich frage mich an dieser Stelle warum es funktioniert das ein PChar mit einem string ausgetauscht werden kann.

peterbelow 21. Aug 2022 11:24

AW: String und PChar frage
 
Zitat:

Zitat von KodeZwerg (Beitrag 1510434)
Ich war auf der Suche nach einem Dialog der sich selbst schließen kann und bin hier im Forum auf das gestoßen:
[DELPHI]

Ich frage mich an dieser Stelle warum es funktioniert das ein PChar mit einem string ausgetauscht werden kann.

Sowas ist generell eine schlechte Idee, weil es von der Art der Implementierung des verwendeten String-Typen und des Mechanismus zur Parameterübergabe abhängig ist. Es funktioniert hier weil eine Variable vom Typ String einen Pointer enthält, der auf das erste Zeichen im String zeigt und die Implementierung auch dafür sorgt, dass der Text mit #0 abgeschlossen wird.

KodeZwerg 21. Aug 2022 12:08

AW: String und PChar frage
 
Zitat:

Zitat von peterbelow (Beitrag 1510439)
... und die Implementierung auch dafür sorgt, dass der Text mit #0 abgeschlossen wird.

Vielen Dank für Deine Antwort peterbelow,
Verzeihung wenn ich nochmal nachfrage, mit Implementierung ist dann die API-Seite gemeint und nicht die Pascal-Seite?

himitsu 21. Aug 2022 12:42

AW: String und PChar frage
 
Der Delphi-String (die LongStrings) ist intern so gebaut, dass es kompatibel zum PChar ist.
Er arbeitet zwar mit einem Längenbyte (Integer), aber hat dennoch zusätzlich auch noch zwei #0 hinter dem String-Ende liegen, weswegen sich String direkt nach PChar casten lässt.

Also ja, man könnte solche Parameter tauschen, aber nur für Lesezugriffe.


Achtung, PChar als Parameter-Typ hat bei einem Leerstring teilweise ein Problem,
denn wenn man einen Parameter nicht übergeben will, dann wird oft NIL verlangt,
aber der PChar-Cast im Delphi hat eine Besonderheit.

Bei einem Leerstring
Delphi-Quellcode:
''
ist der String im Delphi zwar NIL,
aber der Cast gibt in diesem Fall nicht das NIL raus, sondern den Zeiger auf eine "existierende" Stringkonstante mit leerem Text, also auf zwei #0 (
Delphi-Quellcode:
''#0#0
bzw.
Delphi-Quellcode:
#0#0
) und nicht auf NIL.


In diesem Fall würde der umgeschriebene Parameter auf String eventuell das "oft" (nicht immer) bessere Ergebnis liefern.
Ebenso kann man bei einem Cast von String auf PChar mit
Delphi-Quellcode:
Pointer(S)
statt
Delphi-Quellcode:
PChar(S)
arbeiten.

Bei Pointer muß man aber aufpassen, dass mn nicht PChar/PAnsiChar/PWideChar verwechselt, weil der Compiler dort keine Typprüfung machen kann, mit der bekannten Warnung.

Uwe Raabe 21. Aug 2022 12:47

AW: String und PChar frage
 
Zitat:

Zitat von himitsu (Beitrag 1510445)
weswegen sich String direkt nach PChar casten lässt.

Das
Delphi-Quellcode:
PChar(S)
für API-Calls wird ja in der Doku auch so beschrieben. Verwirrend ist lediglich die Deklaration der API-Funktion mit
Delphi-Quellcode:
const string
Parametern. Das weicht dann formal doch recht von der API-Dokumentation ab (obwohl es ja funktioniert).

himitsu 21. Aug 2022 13:27

AW: String und PChar frage
 
Ja, es weicht ab, aber macht einem das Leben auch manchmal einfacher, weil man nicht immer manuell nach PChar casten muß.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:12 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