![]() |
Rückgabe von CommandLineToArgvW
Folgender Code:
Delphi-Quellcode:
Wenn ich PPWideChar und die Funktion nicht selber deklariere, siehe auskommentierten Code, bekomme ich nicht die Argumente, sondern nur die ersten drei Zeichen des Pfades.
//type
//TPWideCharArray = array[0..0] of PWideChar; //PPWideCharArray = ^TPWideCharArray; //function CommandLineToArgvW( lpCmdLine: PWideChar; var NumArgs: Integer): PPWideChar; //stdcall; external 'shell32.dll'; procedure GetCommandLineArgs(Args: TStrings); var NumArgs: Integer; //TempArgs: PPWideCharArray; TempArgs: PPWideChar; i: Integer; begin if CommandLineToArgvW(GetCommandLineW, NumArgs) <> nil then begin try try TempArgs := CommandLineToArgvW(GetCommandLineW, NumArgs); for i := 0 to NumArgs - 1 do Args.Add(TempArgs^[i]); except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally GlobalFree(THandle(TempArgs)); end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin GetCommandLineArgs(ListBox1.Items); end; Was muss ich ändern, damit ich die Datentypen und die Funktion nicht selber deklarieren muss, damit es funktioniert? Entwicklungsumgebung ist Delphi 7, also nix Unicode. |
AW: Rückgabe von CommandLineToArgvW
Delphi-Quellcode:
for i := 0 to NumArgs - 1 do begin Args.Add(TempArgs^); Inc(TempArgs); end; |
AW: Rückgabe von CommandLineToArgvW
Danke funktioniert. Aber warum? Kannst du mir das auch noch erklären?
|
AW: Rückgabe von CommandLineToArgvW
Der Rückgabewert ist ein Zeiger auf den ersten WideChar Zeiger. Also bei mir funkz das mit PPWideCharArray.
|
AW: Rückgabe von CommandLineToArgvW
Hm, OK. Dann habe ich nur den Zugriff versemmelt. ;)
Ja mit PPWideCharArray funktioniert es bei mir auch, nur ich wollte ohne die zusätzliche Deklaration auskommen. |
AW: Rückgabe von CommandLineToArgvW
Ich habe nochmal darüber nachgedacht und mir ist aufgefallen, das der Code, so wie er von mir vorgeschlagen wurde, gleich zwei Memoryleaks produziert. Hier nun eine korregierte Fassung. (Ich gehe davon aus, das die Windows-Funktionen keine Exception erzeugen werden).
Delphi-Quellcode:
procedure GetCommandLineArgs(Args: TStrings);
type TPWideCharArray = array[0..0] of PWideChar; var NumArgs: Integer; TempArgs: PPWideChar; i: Integer; begin TempArgs := CommandLineToArgvW(GetCommandLineW, NumArgs); try if TempArgs <> nil then begin for i := 0 to NumArgs - 1 do Args.Add(TPWideCharArray(TempArgs^)[i]); end else RaiseLastOSError; finally GlobalFree(THandle(TempArgs)); end; end; |
AW: Rückgabe von CommandLineToArgvW
Das heißt, dieser Code
![]() verursacht Speicherlücken? Wo entstehen diese denn? |
AW: Rückgabe von CommandLineToArgvW
Ich habe auch was :)
1. CommandLineToArgvW verwendet LocalAlloc und daher sollte LocalFree verwendet werden (das macht aber in 32bit nichts mehr aus, da es dasselbe ist. Aber MSDN sagt es halt so 2. try/except ist hier garnicht notwendig, ja sogar total falsch, da GetLastError verwendet wird, was falsche Werte liefert, weil keine Winapi so eine Exception wirft (könnte auch eine AV sein) 3. Das Prüfen des Rückgabewertes von CommandLineToArgvW auf nil ist ein Fehler, denn hier wird Speicher alloziert, jedoch nicht freigegeben. Weiterhin gibt es nur zwei Fälle, die ein nil produzieren
|
AW: Rückgabe von CommandLineToArgvW
Der Code
Delphi-Quellcode:
erzeugt zwei Speicherlöcher:
procedure GetCommandLineArgs(Args: TStrings);
var NumArgs: Integer; TempArgs: PPWideChar; i: Integer; begin if CommandLineToArgvW(GetCommandLineW, NumArgs) <> nil then begin try try TempArgs := CommandLineToArgvW(GetCommandLineW, NumArgs); for i := 0 to NumArgs - 1 do begin Args.Add(TempArgs^); Inc(TempArgs); end; except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally GlobalFree(THandle(TempArgs)); end; end; end; Erstes Speicherloch:
Delphi-Quellcode:
denn das Ergebnis wird nicht freigegeben (wie Dezipaitor schon richtig schreibt)
if CommandLineToArgvW(GetCommandLineW, NumArgs) <> nil then
Zweites Speicherloch:
Delphi-Quellcode:
denn TempArgs ist nicht mehr gültig (wegen Inc()).
GlobalFree(THandle(TempArgs));
|
AW: Rückgabe von CommandLineToArgvW
Ok, danke für die Erklärung.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:25 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