Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Wie Callback-Funktion schreiben?
Jacdelad - Mi 05.07.06 19:49
Titel: Wie Callback-Funktion schreiben?
Hallöle,
ich progge in Delphi und XProfan. So, meistens erstelle ich DLLs in Delphi, wenn die XProfan-Funktion dafür entweder zu langsam oder nicht vorhanden ist. So, meine Frage ist nun: Wie kann ich eine Prozeduradresse, die ich übergeben bekomme dann in der DLL aufrufen???
Jac
PS: Ich hoffe, ihr wisst was ich meine...
BenBE - Mi 05.07.06 19:58
Du Meinst sowas hier?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| Function Callback(Foo: Integer): Boolean; begin
end;
type TCallbackProc = function (Something: Integer): Boolean;
procedure LocalProc(Func: TCallbackProc); var I: Integer; begin For I := 0 to 9 do Func(I); end;
LocalProc(@Callback); |
MrSaint - Mi 05.07.06 21:06
Hier musst du natürlich auf die Aufrufkonventionen der Procedures aufpassen. Siehe z.B. stdcall in der OH.
MrSaint
Jacdelad - Do 06.07.06 19:25
Uhh, ich blick in dem Beispiel grad nicht durch. Mir gehts darum, dass ich die Adresse direkt aus dem Profaunaufruf übergebe (also Non-Delphi) und dann die Funktion/Prozedur in Delphi aufrufen will...
BenBE - Do 06.07.06 20:34
Dann brauchst Du in deinem Delphi-Programm Zeilen 6 bis 13 meines Beispiels ...
Zeilen 1-4 und Zeile 15 sind die Dinge aus dem externen Programm. Wie Zeile 15 in XProfan heißt, weiß ich nicht ...
Jacdelad - Do 06.07.06 21:48
Ah, ich glaube ich habs verstanden. Ich melde mich wieder wenns klappt......oder ich völlig am Boden zerstört bin.
Danke,
Jac
Jacdelad - Fr 07.07.06 15:26
Oh, vielen Dank. Ich wurschtel mich jetzt erstmal da durch und melde mich nochmal!
Danke und schönes Wochenende,
Jac
Jacdelad - Sa 08.07.06 17:39
So weit, so gut funktioniert alles. Nun habe ich aber ein neues Problem: Wie erkenne ich, wenn statt eines Zeiger eine "0" übergeben wird (die Callback-Funktion soll also nicht aufgerufen werden...)???Habs mit 0 und NIL probiert...geht irgendwie nicht...
Jac
fidionael - Sa 08.07.06 19:17
Ich weiß nicht genau was du meinst, vielleicht sowas?:
Delphi-Quelltext
1: 2: 3: 4: 5:
| function Aufruf(x: TCallbackProc) : Integer; begin if @x <> nil then Result:=x else Result:=-1; end; |
Jacdelad - So 09.07.06 12:21
Wunderbar, genau das habe ich gesucht. Danke, ich muss mich echt mal in die Ürpblematik Zeiger und so reinknien!
Jac
Motzi - Mi 12.07.06 10:36
Zum Thema Zeiger kann ich dir mein Tutorial auf
http://www.manuel-poeter.de empfehlen.
Zum Überprüfen ob ein Zeiger undefiniert ist (als nil) kann man "Assigned" verwenden, dabei ist es dann egal ob es sich um einen "normalen" Zeiger oder einen Funktions/Methodenzeiger handelt. Dadurch spart man sich dann solche Konstrukte wie
Gruß, Motzi
BenBE - Mi 12.07.06 16:22
Assigned prüft aber auch nur auf nil ... Korrekt wäre aber auf DWORD(@x) and $FFFFF000 <> 0 zu prüfen, da die gesamte erste Speicherpage eine PAGE_FAULT auslöst ...
Motzi - Mi 12.07.06 18:08
Das schon.. aber weißt du einem nicht initialisierten Zeiger jemals einen anderen Wert als nil zu? Und ein Zeiger, dem gar kein Wert zugewiesen wurde (auch nicht nil), kann sowieso überall hin zeigen - da bringt es dann auch nichts zu prüfen ob er irgendwo in die erste Seite zeigt da die Wahrscheinlichkeit das dies der Fall ist doch sehr gering ist! :roll:
BenBE - Mi 12.07.06 21:00
Motzi hat folgendes geschrieben: |
Das schon.. aber weißt du einem nicht initialisierten Zeiger jemals einen anderen Wert als nil zu? |
Jup, passiert bei indirekt über Records addressierte Pointer ... Nicht um sonst Erzeugt
TForm(nil).Show nicht bei exakt
$00000000 die AV, sondern bei (IIRC)
$0000024B...
Motzi hat folgendes geschrieben: |
Und ein Zeiger, dem gar kein Wert zugewiesen wurde (auch nicht nil), kann sowieso überall hin zeigen - da bringt es dann auch nichts zu prüfen ob er irgendwo in die erste Seite zeigt da die Wahrscheinlichkeit das dies der Fall ist doch sehr gering ist! :roll: |
Jup. Korrekterweise müsste man auf einen Zielbereich innerhalb einer GENERIC_READ-Page in einem Code\Daten-Segment prüfen ... Den Aufwand treibt aber keiner ...
Motzi - Do 13.07.06 10:47
TForm(nil).Show erzeugt deshalb eine AV bei
$000002EC weil in diesem Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TCustomForm.SetVisible(Value: Boolean); begin if fsCreating in FFormState then if Value then Include(FFormState, fsVisible) else Exclude(FFormState, fsVisible) else begin if Value and (Visible <> Value) then SetWindowToMonitor; inherited Visible := Value; end; end; |
in der Markierten Zeile auf das private Feld
FFormState zugegriffen wird. Da aber der Self-Pointer nil ist liegt die Adresse in der ersten Speicherseite - soweit hast du recht.
ABER - gehts du jetzt ernsthaft her und überprüfst
DWORD(@Self.FFormState) and $FFFFF000 <> 0 oder nicht einfach doch
Self <> nil?? :roll:
Wenn man mit Objekten oder Zeigern auf Records arbeitet deren Adressen nil sind, so wird in 90% aller Fälle eine AV an einer Adresse ungleich
$00000000 ausgelöst, weil die Felder unterschiedliche Offsets haben. Aber das bedeutet nicht, dass ich dies nicht einfach verhindern kann indem ich die Adresse auf nil überprüfe (egal ob manuell oder mit Assigned)!
Gruß, Motzi
BenBE - Do 13.07.06 21:30
Die Anmerkung war auch eher zur Verdeutlichung, bzw. Erklärung der Funktionsweise der Access Violations unter Windows gedacht ... Im Normalfall ist keiner so verrückt, Zugriffe bis auf das letzte Bit auf Korrektheit zu prüfen ...
Nur zur Ergänzung: Windows bietet zwei Funktionen: IsBadReadPtr und IsBadWritePtr. Wie sie funktionieren, sollte selbsterklärend sein ...
Motzi - Do 13.07.06 21:42
Also ich glaube es führt bei Leuten die sich noch nicht so gut auskennen eher zu mehr Verwirrung als zu besserem Verständnis.. ;)
Und IsBadRead/WritePtr bringt dich auch nicht wirklich viel weiter, da ein nicht initialisierter Zeiger ja auch in einen benutzten Speicherbereich zeigen kann - dann kriegst du oft auch keine AV (zumindest nicht sofort) sondern haust dir einfach irgendwelche anderen Daten zusammen.
Gruß, Motzi
Jacdelad - Fr 14.07.06 17:58
Hm, ja jetzt bin ich verwirrt. Meine DLL funktioniert mit @ und NIL und so ganz prima, hatte bisher noch keinen Fehler. Das mit Assigned schau ich mir aber mal an...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!