![]() |
AW: Warum gibt es hier eine Acess Violation?
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
oder eine statische
procedure
Delphi-Quellcode:
zu. Andernfalls passt der Stack nicht richtig. Je nachdem, was in der Methode gemacht wird kracht es eben oder kracht es nicht.
class procedure
Berücksichtigt man nun das oben beschriebene Verhalten beim Zugriff auf die übergeordnete Variable, kommt es zum Crash, weil der Stack beim Aufruf des Callbacks eben nicht so ist, wie es die Unterroutine erwartet. |
AW: Warum gibt es hier eine Acess Violation?
Ganz herzlichen Dank! Ich ahnte, dass da Dinge im Spiel sind, auf die ich selbst nicht kommen kann.
Zitat:
Ich muss das jetzt erstmal geistig durchdringen. Die Sache mit
Delphi-Quellcode:
ist allerdings nicht auf meinem Mist gewachsen, das habe ich irgendwoher. Das mit dem
TFindeDateienRM
Delphi-Quellcode:
hätte ich ja nicht von allein gewusst.
stdcall
Edit: Vermutlich findest du die ganze Konstruktion nicht gut, aber gibt es einen Weg,
Delphi-Quellcode:
so zu deklarieren, dass es geht?
TFindeDateienRM
|
AW: Warum gibt es hier eine Acess Violation?
Zitat:
Zitat:
|
AW: Warum gibt es hier eine Acess Violation?
FindeDateiRM steht bereits im interface-Teil einer Unit.
Lasse ich das @ weg, kommt (wenig überraschend): Lokale Prozedur wurde Prozedurenvariable zugewiesen. Ich verstehe auch nicht, warum das @ fehlen darf. Es wird doch die Adresse einer Prozedurenvariable übergeben?! |
AW: Warum gibt es hier eine Acess Violation?
Zitat:
Zitat:
Zitat:
TFindeDateiRM ist als
Delphi-Quellcode:
deklariert. Eine lokale Prozedur hat aber trotz gleicher Signatur eine andere Aufrufkonvention. Deswegen sind die beiden nicht Zuweisungkompatibel. Mit dem @-Operator degradierst du die Lokale Prozedur aber zu einem typlosen Pointer und den kann man fast immer zuweisen. Das ändert aber nichts an der Inkompatibilität, sondern übergeht nur die (in diesem Fall durchaus sinnvolle) Typprüfung des Compilers.
procedure(const Verzname:string;const Data:_WIN32_FIND_DATAW;var Abbr:Boolean); stdcall;
|
AW: Warum gibt es hier eine Acess Violation?
Das ist jetzt harter Stoff, aber das würde mich wirklich freuen, das mal zu kapieren.
Ich habe mich vertan:
Delphi-Quellcode:
steht im Interface-Teil. Ich dachte, ich brauche das, damit ich das als Variable übergeben kann. Die Prozedur
TFindeDateienRM = procedure(const Verzname:string;const Data:_WIN32_FIND_DATAW;var Abbr:Boolean); stdcall;
Delphi-Quellcode:
habe ich mehrfach in meinem Code im Einsatz, weil er jeweils verschiedene Aufgaben erledigt und dabei auf die verschiedensten Strukturen zugreifen muss. Realisiert ist das immer als Unterprozedur einer Klassenmethode, auf deren Variablen die Prozedur dann zugreift. Daher keine globale Prozedur. Wie kann man das sonst realisieren (ich meine
procedure FindeDateiRM(const BasisVerz:string;const Data:TWin32FindDataW;var Abbrechen:Boolean); stdcall;
Delphi-Quellcode:
)?
TFindeDateienRM
|
AW: Warum gibt es hier eine Acess Violation?
Die Deklaration von
Delphi-Quellcode:
brauchst du schon um den Parameter zu deklarieren. Allerdings sind hier für die Übergabe keine lokalen Unterroutinen erlaubt, sondern nur globale Prozeduren oder statische Klassenmethoden. Meiner Meinung nach fehlt bei dieser Deklaration noch ein Kontext.
TFindeDateiRM
Wenn du die Deklaration von
Delphi-Quellcode:
nach deinen Bedürfnissen anpassen kannst, dann bietet sich folgende Lösung an:
TFindeDateiRM
Delphi-Quellcode:
Durch das
TFindeDateienRM = procedure(const Verzname:string;const Data:_WIN32_FIND_DATAW;var Abbr:Boolean) of object;
Delphi-Quellcode:
wird zu der Methoden-Adresse noch die Objekt-Instanz übergeben (die Prozedurvariable wird dadurch zu einer Methodenvariable). So kannst du unterschiedliche Klassen deklarieren, die auf die jeweiligen Bedürfnisse zugeschnitten sind. Als Parameter für
of object
Delphi-Quellcode:
wird dann jeweils
FindeDateien
Delphi-Quellcode:
angegeben.
MeineInstanz.FindeDateiRM
Delphi-Quellcode:
TEineKlasse = class
public procedure FindeDateiRM(const Verzname:string;const Data:_WIN32_FIND_DATAW;var Abbr:Boolean); end; TAndereKlasse = class public procedure FindeDateiRM(const Verzname:string;const Data:_WIN32_FIND_DATAW;var Abbr:Boolean); end; ... EineInstanz := TEineKlasse.Create; try FindeDateien(VerzListe[i], '*', False, EineInstanz.FindeDateiRM, Abbrechen); finally EineInstanz.Free; end; ... AndereInstanz := TAndereKlasse.Create; try FindeDateien(VerzListe[i], '*', False, AndereInstanz.FindeDateiRM, Abbrechen); finally Anderenstanz.Free; end;
Delphi-Quellcode:
und
TEineKlasse
Delphi-Quellcode:
halten dann die nötigen Strukturen vor (z.B.
TAndereKlasse
Delphi-Quellcode:
), mit denen die jeweilige Methode
BldListe
Delphi-Quellcode:
arbeiten muss.
FindeDateiRM
Sollte die bisherige Deklaration von
Delphi-Quellcode:
allerdings extern vorgegeben sein, gibt es zwar auch Lösungen, die sind aber alle irgendwie hässlich.
TFindeDateiRM
|
AW: Warum gibt es hier eine Acess Violation?
Vielen Dank. Da mache ich mich mal dran.
Delphi-Quellcode:
kann ich ohne Weiteres anpassen.
TFindeDateiRM
Es ist so, dass ich - hier:) - eigentlich allem folgen kann, was du sagst, aber es nicht zu meinem aktiven Wissen gehört, so dass ich darüber nicht einfach verfügen und die Zusammenhänge erkennen kann. Falls du an diesem trüben Samstag die Zeit aufbringen kannst, würdest du mal die "hässlichen" Lösungen beschreiben? Für den Lerneffekt und das aktive Wissen. Edit: Ich habe es gerade mal probiert und bin schon auf die erste Schwierigkeit gestoßen. Ich muss dann ja
Delphi-Quellcode:
als Klassenmethode implementieren. Aber der Grund für meine Konstruktion mit der Unterprozedur war ja der, dass ich bei dieser Implementation innerhalb von
FindeDateiRM
Delphi-Quellcode:
auf Strukturen der Klassenmethode zugreifen will, die nicht global erreichbar sind.
FindeDateiRM
|
AW: Warum gibt es hier eine Acess Violation?
Zitat:
Was aber geht wäre sowas:
Delphi-Quellcode:
Oder man erweitert
type
TBldListeWrapper = class private FBldListe: TBldListe; public constructor Create(ABldListe: TBldListe); procedure FindeDateiRM(const BasisVerz:string;const Data:TWin32FindDataW;var Abbrechen:Boolean); end; constructor TBldListeQrapper.Create(ABldListe: TBldListe); begin inherited Create; FBldListe := ABldListe; end; procedure TBldListeWrapper.FindeDateiRM(const BasisVerz:string;const Data:TWin32FindDataW;var Abbrechen:Boolean); var Bld:TBld; begin Bld := TBld.Create; Bld.Name := string(Data.cFileName); FBldliste.add(Bld); end; procedure TForm1.ErstelleListe; var Bldliste:TBldliste; begin procedure Intialisiere; begin Bldliste := TBldliste.Create(True); end; procedure ListeDateienAuf; var wrapper: TBldListeWrapper; begin wrapper := TBldListeWrapper.Create(BldListe); try FindeDateien(VerzListe[i],'*',False,wrapper.FindeDateiRM,Abbrechen); finally wrapper.Free; end; end; end;
Delphi-Quellcode:
:
TBldListe
Delphi-Quellcode:
type
TExtendedBldListe = class(TBldListe); public procedure FindeDateiRM(const BasisVerz:string;const Data:TWin32FindDataW;var Abbrechen:Boolean); end; procedure TExtendedBldListe.FindeDateiRM(const BasisVerz:string;const Data:TWin32FindDataW;var Abbrechen:Boolean); var Bld:TBld; begin Bld := TBld.Create; Bld.Name := string(Data.cFileName); add(Bld); end; procedure TForm1.ErstelleListe; var Bldliste:TExtendedBldliste; begin procedure Intialisiere; begin Bldliste := TExtendedBldliste.Create(True); end; procedure ListeDateienAuf; begin FindeDateien(VerzListe[i],'*',False,BldListe.FindeDateiRM,Abbrechen); end; end; |
AW: Warum gibt es hier eine Acess Violation?
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:41 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