Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - procedure als parameter zwecks handlerzuweisung


Sprotti - Do 04.09.08 16:32
Titel: procedure als parameter zwecks handlerzuweisung
hallo,

ich hab da mal zwei Klassen. Die erste soll Prozeduren zur Ereignisbehandlung bereitstellen, also die Handler. Die zweite Klasse soll dann zur Laufzeit diese Handler über den Konstruktor zugewiesen bekommen.
Geht das irgendwie?
Mein Ansatz...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
type
TProcCallback=procedure(Sender:Tb;o:TObject) of object;

Ta=class
private
  myB:Tb;
  procedure DoHandle(o:TObject);
public
  constructor Create();
end;

Tb=class
private
  _pcb:TProcCallback;
  procedure DoSth();
public  
  property Handling:TProcCallback read _pcb write _pcb;
  constructor Create(cbm:TProcCallback);
end;

implementation

constructor Tb.Create(cbm:TProcCallback);
begin
  if Assigned(cbm)then Handling := cbm;  
end;

procedure Tb.DoSth();
begin
  if Assigned(Handling) then Handling(TObject.Create());
end;

constructor Ta.Create();  
begin
  myB:=Tb.Create(DoHandle);
end;

procedure Ta.DoHandle(o:TObject);
begin
end;

...bringt irgendwie nicht das gewünschte Ergebnis. In Tb.DoSth() bekomme ich eine Zugriffsschutzverletzung. Obwohl eine Addr eingetragen wird und Assigned auch true liefert.
Lässt sich die Prozedur als Parameter für eine Prozedur oder Function übergeben? (muß nicht der constructor sein)


Sinspin - Do 04.09.08 17:57
Titel: Re: procedure als parameter zwecks handlerzuweisung
user profile iconSprotti hat folgendes geschrieben:
Lässt sich die Prozedur als Parameter für eine Prozedur oder Function übergeben? (muß nicht der constructor sein)

Ja sicher geht das. Probiere es doch einfach aus! Das geht schneller aus hier auf eine Antwort zu warten ;-)


Sprotti - Fr 05.09.08 08:18

Zitat:

Ja sicher geht das. Probiere es doch einfach aus!


wenn ich s so nicht ausprobiert hätte, könnte ich auch nicht auf die Zugriffsschutzverletzung in DoSth verweisen :wink:
Ich hatte gehofft, jemand könnte mir erklären warum der Zugriff so nicht funktioniert.
Aber wenn es so funktionieren soll werde ich wohl weiter nach falschen Pointern schauen müssen.
Trotzdem erstmal danke fürs reinlesen


Sprotti - Fr 05.09.08 08:46

leider ist der Debugger bei dem Thema auch nicht wirklich hilfreich. Wenn ich mit der Maus in DoSth auf cbm gehe faselt er irgendwas von Ausdrucksfehler :?:
Ich hab jetzt noch eine Änderung ausprobiert, bekomme aber noch immer das selbe Ergebnis

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
type
PProcCallback=^TProcCallback;

Tb=class    
public      
  constructor Create(cbm:PProcCallback);  
end;  

implementation  
constructor Tb.Create(cbm:PProcCallback);  
begin  
  if Assigned(cbm^)then Handling := cbm^;    
end;  

constructor Ta.Create();    
var
  transferPointer:TProcCallback;
begin
  transferPointer:=DoHandle;
  myB:=Tb.Create(@transferPointer);  
end;


Was mach ich denn nur falsch bei der Sache?


iKilledKenny - Fr 05.09.08 09:07

Also was mir beim Drüberlesen über deinen Quellcode aufgefallen ist, ist die unterschiedliche Deklaration der Funktionen.


Delphi-Quelltext
1:
TProcCallback=procedure(Sender:Tb;o:TObject) of object;                    


und


Delphi-Quelltext
1:
procedure Ta.DoHandle(o:TObject);                    


Das kann so ja eigentlich nicht gehen??!!


Sprotti - Fr 05.09.08 09:23

ist richtig und auch nur falsch übernommen
richtig ist auch bei mir

Delphi-Quelltext
1:
procedure Ta.DoHandle(Sender:Tb;o:TObject);                    

deklariert

also, bitte den Ansatz mit dem übergabepointer vergessen. Die erste Version funktioniert. Das Problem war folgendes...

Tb.DoSth wird bei mir in Tc benutzt. Die hatte ich hier nicht angegeben, da ich nicht vermutet hatte, dass diese mit der Sache was zu tun hat.

Allerdings hatte ich vor dem Aufruf von DoSth noch keine Tb Instanz gebildet. Somit war meine TbVariable einfach mal nil.

Das unschöne an dem Ganzen ist, dass der Debugger erst in der DoSth über einen falschen Handler gemeckert hat und nicht schon in Tc über die nicht instanzierte Variable. Dadurch der komplett falsche Suchansatz bei mir.

Vielen Dank Borland