Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi PChar, PWideChar, Array of Char und Windows API (https://www.delphipraxis.net/184944-pchar-pwidechar-array-char-und-windows-api.html)

SyntaxXx 2. Mai 2015 15:16

PChar, PWideChar, Array of Char und Windows API
 
Hallo zusammen,
ich arbeite gerade mit der Windows API.
Jetzt stoße ich dabei auf ein Problem.

Aber vorweg, ich rufe die Methode GetUserName auf.
Windows benutzt dabei folgende Variablen:
LPTSTR lpBuffer
LPDWORD lpnSize

Nach ein wenig Googlen bin ich auf einen Thread hier im Board gestoßen, indem stand, dass das passende Gegenstück von "LPTSTR" "PChar" ist.

Jetzt stellt Delphi aber eine eigene Unit bereit, die die Windows API abbildet.
Und dort wird aber statt "LPTSTR" "PWideChar" verwendet.

Die erste Frage ist, was der Unterschied von PChar und PWideChar ist. Beides sind doch Pointer mit Nullterminierung der Strings.
Da ich aber mit beiden Datentypen einen Fehler bekomme, habe ich mich ein wenig umgeschaut.

Fündig bin ich bei Delphi-Treff geworden.
Dort wird die Methode wie folgt aufgerufen:
Delphi-Quellcode:
function GetUsername: String;
var
  Buffer: array[0..255] of Char;
  Size: DWord;
begin
  Size := SizeOf(Buffer);
  if not Windows.GetUserName(Buffer, Size) then
    RaiseLastOSError; //RaiseLastWin32Error; {Bis D5};
  SetString(Result, Buffer, Size - 1);
end;
Es wird also ein Array of Char benutzt.
Und damit geht's dann auch.

Jetzt stellt sich mir die Frage, wieso?

Wenn ich statt des "Array of Char" eben "PChar" oder "PWideChar" benutze, dann ist nach dem Aufruf von "GetUserName" Buffer leer.
Nur mit dem Array of Char steht in Buffer etwas drin.


Könnt ihr mir helfen?

Dalai 2. Mai 2015 15:53

AW: PChar, PWideChar, Array of Char und Windows API
 
Zitat:

Zitat von SyntaxXx (Beitrag 1300032)
Die erste Frage ist, was der Unterschied von PChar und PWideChar ist. Beides sind doch Pointer mit Nullterminierung der Strings.

Korrekt. Aber das ist nicht alles. PWideChar ist ein konkreter Typ, der eben mit WideChars arbeitet. PChar ist nur eine weitere Deklaration, die bis einschließlich Delphi 2007 dasselbe wie PAnsiChar war, ab D2009 ist es ein PWideChar. Leider kann ich den Unterschied zwischen WideChar und AnsiChar nicht so erklären, dass ich mir sicher bin, es richtig zu tun, auch wenn ich weiß, wo der Unterschied liegt. Bevor ich Unsinn erzähle, überlasse ich das anderen, zumal es diesbzgl. genug Material geben dürfte.

Zitat:

Es wird also ein Array of Char benutzt.
Und damit geht's dann auch.

Jetzt stellt sich mir die Frage, wieso?
Wieso es funktioniert oder warum ein Array of Char benutzt wird?

Zitat:

Wenn ich statt des "Array of Char" eben "PChar" oder "PWideChar" benutze, dann ist nach dem Aufruf von "GetUserName" Buffer leer.
Nur mit dem Array of Char steht in Buffer etwas drin.
Korrekt. Ein PChar ist erstmal nur ein Zeiger auf einen Speicherbereich, konkret auf das erste Zeichen eines Strings bzw. einer Zeichenkette. Da steckt erstmal nichts dahinter, d.h. wenn man PChar verwenden will, muss man den Speicher erst anfordern, auf den der Zeiger zeigt. Das Array of Char im Beispiel hat eine feste Größe, d.h. der Speicher ist bereits angefordert und kann gefüllt werden. Der Vorteil der Verwendung eines Array of Char besteht darin, sich die explizite Anforderung und auch wieder Freigeben des Speichers zu sparen (jedenfalls bei Arrays fester Größe).

MfG Dalai

SyntaxXx 2. Mai 2015 16:06

AW: PChar, PWideChar, Array of Char und Windows API
 
Zitat:

Wieso es funktioniert oder warum ein Array of Char benutzt wird?
Beides ^^


Zitat:

d.h. wenn man PChar verwenden will, muss man den Speicher erst anfordern
Wie sähe denn das Anfordern von Speicher aus?

Hier wird auch mit PChar gearbeitet, ohne das Speicher angefordert wird:
http://www.delphibasics.co.uk/RTL.asp?Name=PChar

Uwe Raabe 2. Mai 2015 16:26

AW: PChar, PWideChar, Array of Char und Windows API
 
Zitat:

Zitat von SyntaxXx (Beitrag 1300039)
Hier wird auch mit PChar gearbeitet, ohne das Speicher angefordert wird:
http://www.delphibasics.co.uk/RTL.asp?Name=PChar

Da wird aber der PChar auf den vorhandenen Speicher des Strings gebogen.

Der schöne Günther 2. Mai 2015 16:38

AW: PChar, PWideChar, Array of Char und Windows API
 
Lies doch mal die Doku zu GetUserName:

Dein festes Array funktioniert da du die Größe schon auf 256 Zeichen festgelegt hast. Den String musst du natürlich auch lang genug machen sonst scheitert die Funktion, wie beschrieben. Ich lasse bei so etwas die Funktion beim ersten mal mit Absicht scheitern da sie mir, laut verlinkter Doku, im Ausgabeparameter
Delphi-Quellcode:
lpnSize
zurückgibt wieviele Zeichen der UserName denn braucht. Und dann kann man seinen String (oder Array) auch so lang machen wie es gebraucht wird und nicht unnötig länger.

[Quote]
Delphi-Quellcode:
procedure printUserName();
var
   userName:   String;
   buffer:      PChar;
   bufferLen:   DWORD;
begin
   bufferLen := 0;
   GetUserName(nil, bufferLen);

   userName := String.Create('?', bufferLen-1);
   buffer := PChar(userName);
   Win32Check( GetUserName(buffer, bufferLen) );
   WriteLn( userName.QuotedString() );
end;

Luckie 2. Mai 2015 21:08

AW: PChar, PWideChar, Array of Char und Windows API
 
Und was steht in bufferlen drin, wenn GetuserName fehl schlägt? :roll:

HolgerX 3. Mai 2015 07:37

AW: PChar, PWideChar, Array of Char und Windows API
 
Hast Du dir die Deklaration der GetUserName mal angeschaut?

Es gib 2 GetUserName unter Windows:

GetUserNameA
-> verwendet PAnsiChar, da es die Ansi-Version ist

GetUserNameW
-> verwendet PWideChar, da es die Wide/Unicode-Version ist

AnsiChar = 1 Byte pro Zeichen
WideChar = 2 Byte pro Zeichen

In den Ansi-Versionen von Delphi wird PChar mit PAnsiChar besetzt und GetUserName verwendet GetUserNameA
In den Unicode-Versionen von Delphi wird Pchar mit PWideChar besetzt und GetUserName verwendet GetUserNameW

So ist es mit allen Windows-API Befehlen, welche über eine ANSI oder UNICODE (= WideString) Version verfügen.
Sprich alle Funktionen, die einen String liefern..

(Nur ne Kurzerläuterung, kein Anspruch auf Vollständigkeit !!)

himitsu 3. Mai 2015 11:27

AW: PChar, PWideChar, Array of Char und Windows API
 
Und aus dem Grund nimmt man nicht einfach so blind PWideChar, nur weil der Editor das so anzeigt.
> GetUserName (Ohne A oder W) vom Delphi eine compilerabhängige Weiterleitung und die ist explizit mit PChar deklariert.

PS: Genau soein Schrot "falsche Typen" verwendet, waren der Hauptgrund für die D2009-Problemchen.

SyntaxXx 4. Mai 2015 07:57

AW: PChar, PWideChar, Array of Char und Windows API
 
Zitat:

Zitat von Luckie (Beitrag 1300062)
Und was steht in bufferlen drin, wenn GetuserName fehl schlägt? :roll:

Es steht dann garnichts drin ('').

Zitat:

Zitat von himitsu (Beitrag 1300083)
GetUserName (Ohne A oder W) vom Delphi eine compilerabhängige Weiterleitung und die ist explizit mit PChar deklariert.

Das heißt also, ich müsste via "GetMem" erst einmal genügend Speicher anfordern, damit in Buffer was drin steht?
Wenn dem so ist, dann verstehe ich auch, weshalb man meistens statt PChar ein Array[0..255] of Char vorfindet.
Denn laut Doku ist die Größe von PChar 8 Bit, was ja einer Maximallänge von 256 Zeichen entspricht, welche ja äquivalent zu den 0..255 ist.

mkinzler 4. Mai 2015 08:00

AW: PChar, PWideChar, Array of Char und Windows API
 
Zitat:

Denn laut Doku ist die Größe von PChar 8 Bit, was ja einer Maximallänge von 256 Zeichen entspricht, welche ja äquivalent zu den 0..255 ist.
Ein PChar ist ein Zeiger und hat deshalb 32Bit in einem 32Bit Betriebssytem. Ein AnsiChar hat 8 Bit. Ein PChar kann aber auch auf eine UnicodeString zeigen ( ab D2009) dann hat ein Char 16 Bit. Die Größe des Buffers hat damit nichts zu tun.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:22 Uhr.
Seite 1 von 2  1 2      

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