![]() |
AccessViolation bei CallBack
Hallo.
Ich versuche gerade etwas mit Callbacks zu machen, erhalte aber eine AV...
Delphi-Quellcode:
(Hintergrund: DownloadOrSynchronize ist eine Funktion, die in einer gemeinsam genutzten PAS-Datei steht. Die einzelnen Projekte, die auf diese Funktion zurückgreifen, haben jeweils ihre eigene Art, dem Benutzer den aktuellen Status in Labels zu vermitteln. Daher Callback)
type
TDownloadCallBackStatus = procedure(FilesDownloaded: Integer) of object; PDownloadCallBackStatus = ^TDownloadCallBackStatus; Txxx = class(T...) private {...} public {...} procedure DownloadOrSynchronize(SearchString: string; OnlySync: boolean; CallBackStatus: PDownloadCallBackStatus); end; procedure Txxx.DownloadOrSynchronize(SearchString: string; OnlySync: boolean; CallBackStatus: PDownloadCallBackStatus); var begin {...} if Assigned(CallBackStatus) then begin CallBackStatus^(j); // <-- EACCESSVIOLATION end; {...} end; procedure CallBack(FilesDownloaded: Integer); begin MainForm.label_x.Caption := inttostr(FilesDownloaded); end; procedure TMainForm.btn_download_click(Sender: TObject); begin {...} AOBJ.DownloadOrSynchronize(edt_tags.Text, chk_nodownload.Checked, @CallBack); {...} end; Ich habe jetzt schon relativ viele Varianten zu Callbacks gesehen, aber nicht alle Funktionieren bei mir. Dieser Code ist nun der erste, den ich Kompilieren konnte. Hat jemand eine Idee, wie das geht? Gruß blackdrake |
Re: AccessViolation bei CallBack
Las mal den Zeiger weg, dann klappt das auch.
Delphi-Quellcode:
type
TDownloadCallBackStatus = procedure(FilesDownloaded: Integer) of object; Txxx = class(T...) private {...} FDownloadCallBackStatus:TDownloadCallBackStatus; public {...} property OnDownloadCallBackStatus:TDownloadCallBackStatus read FDownloadCallBackStatus write FDownloadCallBackStatus; procedure DownloadOrSynchronize(SearchString: string; OnlySync: boolean); end; procedure Txxx.DownloadOrSynchronize(SearchString: string; OnlySync: boolean); var begin {...} if Assigned(FDownloadCallBackStatus) then FDownloadCallBackStatus(j); {...} end; procedure CallBack(FilesDownloaded: Integer); begin MainForm.label_x.Caption := inttostr(FilesDownloaded); end; procedure TMainForm.btn_download_click(Sender: TObject); begin {...} AOBJ.OnDownloadCallBackStatus:=CallBack; AOBJ.DownloadOrSynchronize(edt_tags.Text, chk_nodownload.Checked); {...} end; |
Re: AccessViolation bei CallBack
Erstens muss du dich entscheiden, ob dein Callback-Parameter freie Routinen oder Methoden annehmen soll. Mit der Klausel "of object" sagst du, dass es eine Methode sein muss, aber du willst dann eine freie Routine übergeben.
Zweitens: Wozu ein Zeiger auf einen Zeiger? Das ist hier absolut unnötig. @Callback gibt den Funktionszeiger zurück, aber nicht die zusätzliche Indirektion, die du eingebaut hast. Daher kommt auch die Zugriffsverletzung. |
Re: AccessViolation bei CallBack
Hallo omata und Apollonius.
@omata: Vielen Dank für die Korrektur! Funktioniert prima. Ich musste lediglich das "of object" noch wegnehmen. Zitat:
Zitat:
Ich finde die Ausführung von omata mit den properties elegant gelöst, da ich ja sowieso in einer Klasse arbeite. Deswegen werde ich diesen Code auch so behalten. Aber wie würde mein Code in funktionierender Fassung aussehen, wenn ich eine Methode/Routine Prozedur/Funktion direkt an eine Funktion weitergeben möchte, ohne diese vorher als Property oder Variable zu setzen? Ist Interessehalber, ich möchte ja irgendwie auch was dabei gelernt haben... Gruß blackdrake |
Re: AccessViolation bei CallBack
Zitat:
Eine Methode gehört zu einer Klasse und eine freie Prozedur nicht (deshalb ist sie auch frei) |
Re: AccessViolation bei CallBack
Zitat:
Delphi-Quellcode:
type
TDownloadCallBackStatus = procedure(FilesDownloaded: Integer) of object; Txxx = class(T...) private {...} FDownloadCallBackStatus:TDownloadCallBackStatus; public {...} property OnDownloadCallBackStatus:TDownloadCallBackStatus read FDownloadCallBackStatus write FDownloadCallBackStatus; procedure DownloadOrSynchronize(SearchString: string; OnlySync: boolean); end; TMainForm = class(TForm) private procedure CallBack(FilesDownloaded: Integer); public end; procedure Txxx.DownloadOrSynchronize(SearchString: string; OnlySync: boolean); var begin {...} if Assigned(FDownloadCallBackStatus) then FDownloadCallBackStatus(j); {...} end; procedure TMainForm.btn_download_click(Sender: TObject); begin {...} AOBJ.OnDownloadCallBackStatus:=CallBack; AOBJ.DownloadOrSynchronize(edt_tags.Text, chk_nodownload.Checked); {...} end; procedure TMainForm.CallBack(FilesDownloaded: Integer); begin Label_x.Caption := inttostr(FilesDownloaded); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:39 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 by Thomas Breitkreuz