Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi String 2 PChar ? (https://www.delphipraxis.net/1024-string-2-pchar.html)

andi_hauser 9. Okt 2002 00:15


String 2 PChar ?
 
Wie kan ich einen String in ein PChar Format bekommen. Brauche diese Umwandlung für ein schnelles Kopieren von Files.

Folgende Zeile funktioniert aus genau diesem Grund nicht. (eh klar!)

Copyfile('C:\autoexec.bat',Edit1.text,alreadyexist s);

ThanX4Help :freak:

Christian Seehase 9. Okt 2002 00:46

Moin Andi,

das geht einfach so:
Code:
  Copyfile('C:\autoexec.bat',PChar(Edit1.text),alreadyexists);
Einen Thread, wo's um das Kopieren geht, hatten wir gerade vor ein paar Tagen.
Such' am Besten mal nach SHFileOperation.

Luckie 9. Okt 2002 01:13

Oder:
Code:
Copyfile('C:\autoexec.bat',@Edit1.text[1],alreadyexists);
Mir wurde mal gesagt, das mit PChar wÜrde nur wegen der Compiler Magic funktionieren.
:roll:

sakura 9. Okt 2002 08:39

@Luckie: Bist Du Dir sicher, dass Dein Ansatz immer einwandfrei funktionert :?: Immerhin hat ein Editfeld i.A. kein #0 Zeichen am Ende, woran ja auch das Ende eines PChar erkannt wird.

Motzi 9. Okt 2002 10:41

Theoretisch funktionieren beide Varianten... das mit dem @..[1] wird aber bei einer Objekt-Eigenschaft funktionieren, da eine Eigenschaft schließlich nur eine Schnittstelle über Zugriffsmethoden auf eine private Variable darstellt kann auch keine Adresse ermittelt werden.

Aber es gibt auch andere Unterschiede zwischen PChar(..) und @..[1]. Mann muss nur mal ein paar Test mit einer API-Funktion machen, die einen String in einem PChar ablegt:

Version1:
Code:
var
  String1, String2: String;

String1 := 'Test';
String2 := String1;

IrgendeineAPIFunktionDieDatenImStringAblegt(PChar(String1));

ShowMessage(String1);
ShowMessage(String2);
Version2:

Code:
var
  String1, String2: String;

String1 := 'Test';
String2 := String1;

IrgendeineAPIFunktionDieDatenImStringAblegt(@String1[1]));

ShowMessage(String1);
ShowMessage(String2);
Die ergebnisse werden sich unterscheiden.. ein einem Fall sind String1 und String2 ident (obwohl nur String1 über die API-Funktion geändert wurde). Ich bin mir zwar nicht ganz sicher wie der Code dazu ausschaun muss (eventuell muss man ihn ein bisschen anpassen) aber ich hab schonmal ein paar Tests gemacht mit genau diesem Ergebnis. Aber genau um diesen Fall zu verhindern gibt es die Funktion UniqueString.

sakura 9. Okt 2002 10:53

Zitat:

Zitat von Motzi
Die ergebnisse werden sich unterscheiden.. ein einem Fall sind String1 und String2 ident (obwohl nur String1 über die API-Funktion geändert wurde). Ich bin mir zwar nicht ganz sicher wie der Code dazu ausschaun muss (eventuell muss man ihn ein bisschen anpassen) aber ich hab schonmal ein paar Tests gemacht mit genau diesem Ergebnis. Aber genau um diesen Fall zu verhindern gibt es die Funktion UniqueString.

Meine Ergebnisse (nutze GetTempPath):

Version 1: Access Violation :|
Version 2: String 1 hat das Ergebnis, String 2 den ursprünlichen Wert.

Insgesamt, wie erwartet, da dass Casten eines Strings in ein PChar für variable Parameter nicht als sicher gilt.

Christian Seehase 9. Okt 2002 13:01

Moin Sakura,

die Variante mit @...[1] funktioniert immer, da Delphi einen String automatisch mit #00 beendet.

Ich hab's jetzt auch einmal mit GetTempPath ausprobiert: Kein Problem.

Allerdings hatte mich das Ergebnis doch verblüfft.
Zuerst hatte ich an ein Problem mit der Implementation von GetTempPath durch Borland gedacht, und mir die Funktion noch einmal selber importiert. Ergebnis: Es trat das gleiche Problem auf. :shock:

Daraufhin habe ich mir das Ganze mal im CPU Fenster angesehen. In der PChar-Variante wird LStrToPChar aufgerufen, was dann dafür sorgt, dass String1 und String2 den gleichen Wert bekommen, in der @..[1]-Version hingegen, wird, an der gleichen Stelle, UniqueString aufgerufen.
Als ich dann mal einen kleinen Blick in die Hilfe zu UniqueString geworfen hatte, kam ich zu dem Schluss, künftig auf die Parameterübergabe, im Zusammenhang mit API's auf PChar zu verzichten, falls ich denn eine String Variable übergeben will :oops:
Die @..[1] Variante ist wohl die einzig Richtige, zumindest, wenn man nicht selber zusätzlich UniqueString aufrufen will.
Ein Problem wird's allerdings erst, wenn, wie Motzi sagte, die Funktion etwas in den String schreiben muss.

Luckie 9. Okt 2002 13:10

Das stammt übrigens von Assarabad. Er hatte mich mal darauf angesprochen, weil ich in einem Programm immer mit PChar gecastet hatte.

sakura 9. Okt 2002 13:13

Zitat:

Zitat von Luckie
Das stammt übrigens von Assarabad. Er hatte mich mal darauf angesprochen, weil ich in einem Programm immer mit PChar gecastet hatte.

Das casten mit PChar hat aber auch seine Berechtigung. Zum Beispiel, wenn man davon ausgehen kann, das der String nicht durch die aufgerufene Methode manipuliert wird. Dann spart man dadurch natürlich wertvolle Processorresourcen.

Christian Seehase 9. Okt 2002 16:41

Moin Sakura,

Zitat:

Dann spart man dadurch natürlich wertvolle Processorresourcen.
Kommt natürlich darauf an, wie gross der Unterschied in der Prozessorauslastung zwischen UniqueString und LStrToPChar ist, denn eine von Beiden wird ja auf jeden Fall aufgerufen.
Und so in den Einzelheiten habe ich mir den Ablauf denn auch nicht angesehen.

Allerdings wird man, zumindest wenn man selber API Strukturen deklarieren will, nicht um PChar rumkommen können.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:40 Uhr.
Seite 1 von 2  1 2      

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