![]() |
Mit PChar arbeiten
hi,
da bin ich wieder 8). Also ich habe mal eine frage zum thema PChar... Da ich immer nur mit strings gearbeitet habe (vcl), frag ich mich wie ich mit PChars umzugehen habe, das fällt mir nämlich ziemlich schwer... Z.B hatte ich eben gerade wieder so ein Problem das ich einen PChar erweitern wollte:
Delphi-Quellcode:
aber das geht natürlich nicht weil "'System32\'" ja ein string ist...
wDir := wDir + 'System32\';
geht das auch ohne hin und her konvertiereri mit string() und PChar() ? |
Re: Mit PChar arbeiten
Äh, stört´s dich wenn ich antworte? ;)
Keine Sorge, das steht zwar sicher auch in den Tutorials, aber nicht als Extra-Kapitel. Schau mal im PSDK nach den "lstr*"-Funktionen. In deinem Fall
Delphi-Quellcode:
Wie gesagt, PSDK: lstrcpy, lstrcmp, lstrcat, lstrlen, usw. Meist gibt´s auch Versionen für Widechars, erkennbar am W, bspw. "lstrcpyW" usw.
lstrcpy(wDir,'c:\windows'); // <-- kopiert "c:\windows" in "wDir"
lstrcat(wDir,'\System32'); // <-- hängt "\System32" an "wDir" an |
Re: Mit PChar arbeiten
Zitat:
Ich weis, Mathias hat die antwort jetzt schon gepostet, aber liegt des "Problem" nicht eher an dem + ? Wenn wDir vom Typ PChar ist, und man zum Beispiel:
Delphi-Quellcode:
schreiben würde, ging das doch auch, weil Delphi 'System32\' dann als PChar-Konstante speichert,oder irre ich mich jetzt da :gruebel:
wDir := 'System32\'
|
Re: Mit PChar arbeiten
Zitat:
Delphi-Quellcode:
wDir := pchar(wDir + 'System32\');
Zitat:
Delphi-Quellcode:
schreibst.
wDir := 'System32\';
btw: Über den Sinn, an "wDir" (die Vermutung liegt nahe, dass die Variable den Namen des Windows-Verzeichnisses enthält) noch das Systemverzeichnis anzuhängen, will ich mal nicht streiten. Vielleicht ist das reale Beispiel ein anderes, ansonsten wäre wohl "GetSystemDirectory" eine Idee. :mrgreen: Aber man kann ja auch programm-intern weiter mit Strings arbeiten. Ich habe für ein Programm bspw. mal den Ordner "%windir%\help" benötigt, und dafür habe ich mir eine Funktion geschrieben, die mir den Ordner wie gewohnt als String zurückliefert:
Delphi-Quellcode:
Und damit ließ sich a) gut arbeiten, und b) das Casten nach pchar war im Bedarfsfall auch kein Problem.
function GetWinHelpDir: string;
begin SetLength(Result,GetWindowsDirectory(nil,0) + 1); SetLength(Result,GetWindowsDirectory(@Result[1],length(Result))); if(Result <> '') then Result := Result + '\help\'; end; |
Re: Mit PChar arbeiten
Moin!
Zitat:
Delphi-Quellcode:
Was aber genauso wenig laufen würde, da er IMHO hier nur die Adressen zusammen rechnet. Problem bei PChar ist, das es Zeicher auf ein Array von Char ist und Delphi bei Zeigern keine grossen Automatismen mitbringt - er rechnet dann eher mit den Zeigern. Daher nutze die oben beschriebenen lstrcat(), etc Funktionen oder die PChar Funktionen aus der SysUtils (StrCat)...
wDir := wDir + PChar('System32\');
MfG Muetze1 |
Re: Mit PChar arbeiten
Ein bisschen aus dem Zusammenhang gerissen, sorry, aber -
Zitat:
Blödes Beispiel mit dem Record für "SHBrowseForFolder", aber es geht:
Delphi-Quellcode:
Dagegen würde dein Vorschlag von oben
GetMem(bla,MAX_PATH); // var bla : pchar;
try ZeroMemory(bla,sizeof(bla)); lstrcpy(bla,'Hallo, Du! '); // "BrowseInfo" mit Werten füllen ZeroMemory(@BrowseInfo,sizeof(BrowseInfo)); { ... } BrowseInfo.lpszTitle := pchar(bla + 'Wähle einen Ordner!'); // usw. { ...} finally FreeMem(bla); end;
Delphi-Quellcode:
nicht funktionieren sondern die Compilermeldung
BrowseInfo.lpszTitle := bla + pchar('Wähle einen Ordner');
Zitat:
Wenn du allerdings kein pchar benutzt sondern selbst ein Zeichenarray deklarierst und als Ziel benutzt, dann funktioniert beides nicht:
Delphi-Quellcode:
In dem Fall brauchst du API- oder SysUtils-Funktionen.
var
bla : array[0..MAX_PATH]of char; begin bla := 'Hallo Du! '; // [Fehler] Unit1.pas(31): Inkompatible Typen: 'Array' und 'PChar' bla := pchar(bla + 'Wähle einen Ordner'); // [Fehler] Unit1.pas(32): Operator ist auf diesen Operandentyp nicht anwendbar bla := bla + pchar('Wähle einen Ordner'); end; Es ist also eine Typfrage. Aber ich nehme an, dass du das auch sagen wolltest? |
Re: Mit PChar arbeiten
Moin!
Genau das wollte ich sagen - und ich sagte auch extra, das es so genauso wenig laufen würde. Das mit der Compilermeldung war mir auch ohne Compiler klar. Somit meinen wir beide das gleiche und mein vorheriger Post war in dem Sinne unnötig - sorry. MfG Muetze1 |
Re: Mit PChar arbeiten
Kein Problem. Lieber einmal mehr und zu ausführlich was schreiben, als einmal zu wenig ... ;)
|
Re: Mit PChar arbeiten
oha wurde hier viel geschrieben :shock:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Alles in allem - DANKE für die antworten/tips :thuimb: |
Re: Mit PChar arbeiten
Zitat:
Zitat:
![]() Ein Beispiel hatte ich ja genannt, ansonsten bleib bei "lstrcat" (API-Funktion) oder der passenden SysUtils-Funktion. Das ist der sichere und bessere Weg. |
Re: Mit PChar arbeiten
Werd ich machen mathis, danke für die mühe ;). Ging mir da nur mehr ums Prinzip wie das mit dem #0 zeichen ist. :)
Achja, eine weitere Frage habe ich und zwar...PChar kann man ja "einfach so" deklarieren und benutzen, richtig? (scheint ja so) Wozu gibt es denn Beispiele wie diese hier(aus der Delphi-Hilfe):
Delphi-Quellcode:
ich meine wozu ist da Getmem gut wenns auch ohne geht?
var
F: file; Size: Integer; Buffer: PChar; begin AssignFile(F, 'test.txt'); Reset(F, 1); try Size := FileSize(F); GetMem(Buffer, Size); try BlockRead(F, Buffer^, Size); ProcessFile(Buffer, Size); finally FreeMem(Buffer); end; finally CloseFile(F); end; end; |
Re: Mit PChar arbeiten
Das ist anders gemeint -
Wenn du bspw. mit DLLs arbeiten willst/musst, die aber Strings als Parameter erwarten, dann ist normalerweise diese "ShareMem"-Unit notwendig. (War doch so, @all?) Jedenfalls kannst du die Parameter aber auch als "pchar" deklarieren, weil du dann ja keinen Speicher erzeugst, sondern (vereinfacht ausgedrückt; die Profis mögen es mir nachsehen) weil du auf den Speicherbereich der übergebenen "Strings" zugreifst. Aus dem Grund brauchst du in so einem Fall:
Delphi-Quellcode:
keinen Speicher deklarieren, weil ja der pchar (Muetze1 sagte es schon) ein Zeiger auf das Zeichenarray ist.
procedure ShowMe(const p: pchar);
begin MessageBox(0,p,nil,0); end; var ca : array[0..MAX_PATH]of char; s : string; begin ca := 'Hallo, Welt!'; ShowMe(ca); s := 'Hallo, Welt!'; ShowMe(pchar(s)); end. Anders sieht es aus, wenn du in deinem Programm mit einem PChar arbeiten willst/musst, bspw. wenn du vorher nicht weißt ob ein
Delphi-Quellcode:
ausreichen wird. Denke bspw. an "GetWindowsDirectory". Diese Funktion liefert, wenn der Puffer zu klein ist, die Anzahl der benötigten Bytes (= Zeichen) zurück. Nach dem Muster funktioniert ja auch die von mir weiter oben gepostete Funktion, die den "%windir%\help"-Ordner zurückliefert - nur, dass ich dort anstelle des PChar eben den String (Result) benutzt habe.
ca : array[0..MAX_PATH]of char;
In so einem Fall musst du den Speicher(bereich) mit "GetMem" erzeugen, sonst ist deine PChar-Variable nur ein Pointer, und jeder Versuch, sie zu verwenden oder mit Inhalt zu füllen, hat einen Fehler zur Folge. |
Re: Mit PChar arbeiten
Gut erklät, danke sehr :thuimb:
|
Re: Mit PChar arbeiten
Ich danke dir. :mrgreen:
Hier ist so ein Beispiel:
Delphi-Quellcode:
Wenn du da mal das Erstellen des Speichers weglässt, dann kracht´s ... ;)
procedure TForm1.Button1Click(Sender: TObject);
var p : pchar; dwLen : dword; begin // folgender Witz: Wenn der Puffer zu klein ist, dann // liefert "GetWindowsDirectory" die erforderliche // Größe zurück, DAS #0-ZEICHEN EINGESCHLOSSEN ... dwLen := GetWindowsDirectory(nil,0); if(dwLen > 0) then begin GetMem(p,dwLen); try ZeroMemory(p,dwLen); // ... da der Puffer nun groß genug ist, liefert // die Funktion die Anzahl der kopierten Zeichen // zurück, die abschließende #0 diesmal NICHT // eingeschlossen (deswegen "dwLen - 1") if(GetWindowsDirectory(p,dwLen) = dwLen - 1) and (p[0] <> #0) then MessageBox(0,p,nil,0); finally FreeMem(p); end; end; end; |
Re: Mit PChar arbeiten
So ein Beispiel habe ich gebraucht, ich glaube ich verstehe es hehe 8)
Danke nochmal für das schreiben des Codes :thuimb: |
Re: Mit PChar arbeiten
Hier hast du noch ein Beispiel (dann hör ich aber auch auf, dich zu nerven) aus der Rubrik: "Es ist zwar ein PChar, aber ..." -
Die Funktion [msdn]"InternetCrackUrl"[/msdn] zerlegt einen Grafen (;)) in seine Bestandteile; sprich: Host, Schema, usw. Die entsprechenden Membervariablen sind zwar als pchar deklariert, allerdings dienen sie hier der Ausgabe der Daten. Das heißt, die Funktion erwartet von dir, dass du einen Puffer bereitstellst, der groß genug ist.
Delphi-Quellcode:
Wenn du denkst, dass das statische Array (0-MAX_PATH) nicht ausreicht, dann kannst du auch hier mit "pchar"-Variablen arbeiten, wobei du dann natürlich den Puffer vorher mit "GetMem" erzeugen musst. Ansonsten rumpelt´s wieder ...
procedure TForm1.Button2Click(Sender: TObject);
const szUrl = 'http://www.delphipraxis.net/topic28303_profil+temp+verzeichniss.html'; var url : TUrlComponents; scheme, buf, urlpath : array[0..MAX_PATH]of char; begin ZeroMemory(@url,sizeof(url)); url.dwStructSize := sizeof(url); url.lpszHostName := buf; url.dwHostNameLength := sizeof(buf); url.lpszScheme := scheme; url.dwSchemeLength := sizeof(scheme); url.lpszUrlPath := urlpath; url.dwUrlPathLength := sizeof(urlpath); if(InternetCrackUrl(szUrl,length(szUrl),0,url)) then MessageBox(0,pchar(Format('Host: %s' + #13#10 + 'Schema: %s' + #13#10 + 'URL: %s',[buf,scheme,urlpath])),nil,0); end; So, genug jetzt. :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz