AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi PChar, PWideChar, Array of Char und Windows API
Thema durchsuchen
Ansicht
Themen-Optionen

PChar, PWideChar, Array of Char und Windows API

Ein Thema von SyntaxXx · begonnen am 2. Mai 2015 · letzter Beitrag vom 4. Mai 2015
Antwort Antwort
Seite 1 von 2  1 2      
SyntaxXx

Registriert seit: 14. Dez 2008
328 Beiträge
 
Delphi XE4 Architect
 
#1

PChar, PWideChar, Array of Char und Windows API

  Alt 2. Mai 2015, 16:16
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?
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#2

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

  Alt 2. Mai 2015, 16:53
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
  Mit Zitat antworten Zitat
SyntaxXx

Registriert seit: 14. Dez 2008
328 Beiträge
 
Delphi XE4 Architect
 
#3

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

  Alt 2. Mai 2015, 17:06
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
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#4

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

  Alt 2. Mai 2015, 17:26
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

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

  Alt 2. Mai 2015, 17:38
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 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;
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

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

  Alt 2. Mai 2015, 22:08
Und was steht in bufferlen drin, wenn GetuserName fehl schlägt?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#7

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

  Alt 3. Mai 2015, 08:37
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 !!)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 3. Mai 2015, 12:27
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.
$2B or not $2B
  Mit Zitat antworten Zitat
SyntaxXx

Registriert seit: 14. Dez 2008
328 Beiträge
 
Delphi XE4 Architect
 
#9

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

  Alt 4. Mai 2015, 08:57
Und was steht in bufferlen drin, wenn GetuserName fehl schlägt?
Es steht dann garnichts drin ('').

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.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#10

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

  Alt 4. Mai 2015, 09:00
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.
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 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