![]() |
Delphi-Version: 2010
Funktion die TStrings zurückgibt
Delphi-Quellcode:
Ich habe beim zweiten oder dritten Mal aufrufen das Problem, das ich einen AccessViolation-Fehlermeldung bekomme in der FOR-Schleife. Desweiteren wird das Ergebnis auch nicht wie gewollt mit den neu ermittelten Werten überschrieben.{...} FPaperTrays : TStrings; {...} function TPrinterCustom.GetPaperTrays: TStrings; var pDevMode : PDeviceMode; bin : array[0..255,0..23] of Char; i : DWORD; Res : DWORD; PPrinter : PPrinterInfo2; begin if (FPaperTrays = nil) then begin try FPaperTrays := TStringList.Create; except FPaperTrays.Free; FPaperTrays := nil; raise; end; end; FPaperTrays.Clear; if FAllInfos.Count <> 0 then begin PPrinter := FAllInfos.Items[FPrinterIndex]; pDevMode := nil; Res := DeviceCapabilities(PPrinter^.pPrinterName, PPrinter^.pPortName, DC_BINNAMES, PChar(@(bin[0][0])), pDevMode); for i := 0 to Res-1 do FPaperTrays.Append(bin[i]); end; Result := FPaperTrays; end; Was mache ich falsch und was könnte man besser machen ? Das Ergebnis soll eine Liste mit allen Papierschächten des Druckers sein. |
AW: Funktion die TStrings zurückgibt
Eine Sache machst du schon mal falsch (weiß aber nicht ob's daran liegt)
Und zwar: wenn im Konstruktor ne Exception geworfen wird, dann darf der Destruktor nicht aufgerufen werden. In diesem Fall sorgt Delphi schon dafür dass das nichts überigbleibt, ein .Free könnte also in einer AV münden. Wird eventuell irgendwo die Liste, die du zurückgibts mit .Free zerstört? Das könnte sehr gut die Fehlerursache sein. Ich glaube nämlich der Aufruf von TStringlist.Create dürfte fast nie fehlschlagen. Falls FPaperTrays ein privates feld deiner Klasse ist, würde ich das auch nicht "herausgeben" - besser wäre hier ein Parameter
Delphi-Quellcode:
in den das hineingeschrieben wird. Dann brauchst du dich auch nicht mehr um den Konstruktor kümmern.
const x:TStrings
|
AW: Funktion die TStrings zurückgibt
Der Code:
Delphi-Quellcode:
ist Blödsinn. Wenn nichts erzeugt werden kann, kann auch nichts freigegeben werden.
if (FPaperTrays = nil) then
begin try FPaperTrays := TStringList.Create; except FPaperTrays.Free; FPaperTrays := nil; raise; end; end; Das Reicht:
Delphi-Quellcode:
Wie erzeugst du die StringListe und wie gibst du sie wieder frei? das sind nicht ganz irrelevante Codeteile.
if (FPaperTrays = nil) then
FPaperTrays := TStringList.Create; else ...; ...; |
AW: Funktion die TStrings zurückgibt
Ich würde aus der Funktion eine Prozedur machen, die ein TStrings-Objekt als Parameter annimmt. Somit ist die aufrufende Routine für die Instanzierung verantwortlich.
|
AW: Funktion die TStrings zurückgibt
Zitat:
Zitat:
|
AW: Funktion die TStrings zurückgibt
Wenn das Methoden einer Klasse sind, warum kennen sie dann nicht die StringListe? Da braucht man doch gar nichts zu übergeben und andauert wieder neu zu erstellen, nur bei Bedarf leeren.
|
AW: Funktion die TStrings zurückgibt
Achso, die ist im protected teil, ja dann aist das was anderes :mrgreen:
Ich tippe mal, du hast noch irgendwo ein
Delphi-Quellcode:
stehen - das wird aufgerufen, und das Objekt ferigegeben. Sobald dann die Methode nochmal aufgerufen wird, knallts.
FPaperTrays.Free;
Denk' dran: ein ".Free" setzt den Zeiger nicht zurück auf nil, d.h. deine Abfrage ist nur ganz am Anfang beim ersten Mal von Bedeutung. Und dann könnte man das erstellen der Stringliste eigentlich auch in den Konstruktor packen und nur noch leeren und wiederbefüllen. |
AW: Funktion die TStrings zurückgibt
Moin Rolf,
die Umsetzung von Detlefs Idee würde, z.B., so aussehen:
Delphi-Quellcode:
Vorteil:
procedure TPrinterCustom.GetPaperTrays(const APaperTrays : TStrings);
var pDevMode : PDeviceMode; bin : array[0..255,0..23] of Char; i : DWORD; Res : DWORD; PPrinter : PPrinterInfo2; begin APaperTrays.Clear; if FAllInfos.Count <> 0 then begin PPrinter := FAllInfos.Items[FPrinterIndex]; pDevMode := nil; Res := DeviceCapabilities(PPrinter^.pPrinterName, PPrinter^.pPortName, DC_BINNAMES, PChar(@(bin[0][0])), pDevMode); for i := 0 to Res-1 do APaperTrays.Append(bin[i]); end; end; Man erhält eine klarere Struktur für das Erzeugen und Freigeben der Stringliste. |
AW: Funktion die TStrings zurückgibt
Ganz genau. Ich würde nur noch in der ersten Zeile auf Assigned prüfen.
Delphi-Quellcode:
if not Assigned(APaperTrays) then
raise Exception.Create('Was soll ich denn hier füllen?'); |
AW: Funktion die TStrings zurückgibt
Danke Christian, Danke Detlef. Ich glaube ich werde in der Klasse alle TStrings-Rückgaben so umschreiben wie Christian es gemacht hat. Dann habe ich doch eine saubere Struktur drin. Oder gibt es dagegen etwas einzuwenden ?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:01 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