AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interfaceliste bei einem Auto-Objekt

Ein Thema von tgoessi · begonnen am 7. Jun 2005 · letzter Beitrag vom 7. Jun 2005
Antwort Antwort
tgoessi

Registriert seit: 31. Mai 2005
34 Beiträge
 
Delphi 5 Enterprise
 
#1

Interfaceliste bei einem Auto-Objekt

  Alt 7. Jun 2005, 12:06
Hallo

Bei einem TAutoObject mit ciMultiInstance wird bei jedem Zugriff von einem externen Prozess ein neues Interface erzeugt.
Wie kann ich eine Referenzliste auf alle diese erzeugten Interfaces erhalten?
Es geht darum vom Serverprozess eine Meldung an alle vorhandenen Interfaces zu senden.
Die erzeugten Interfaces in einer TInterfaceList zu speichern funktioniert nicht richtig, da zusätzliche Referenzen erzeugt werden, was zur Folge hat, dass das Objekt nicht mehr freigegeben wird, wenn alle externen Proesse, die darauf zugreifen beendet werden.

Wie kann man das am besten lösen?
Tom
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Interfaceliste bei einem Auto-Objekt

  Alt 7. Jun 2005, 13:35
Das Schlagwort für Events vom Server zum Client ist die . Hierzu wird eine weitere (Event-)Schnitttelle definiert, welche jetzt vom Client implementiert wird um vom Server aufgerufen wird.

Dazu holst Du dir auf jedenfall mal das EventSinkImp-Tool von Binh Ly und am besten auch gleich das Buch von A Kosch über COM/DCOM/COM+ um auch die Probleme z.B. bezüglich Rechtevergabe zu verstehen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
tgoessi

Registriert seit: 31. Mai 2005
34 Beiträge
 
Delphi 5 Enterprise
 
#3

Re: Interfaceliste bei einem Auto-Objekt

  Alt 7. Jun 2005, 14:26
Genauso hab ich es gemacht.
Ich speichere die self-Pointer in der initialize-Methode in einer Interfaceliste. Das funktioniert soweit ok. Ich kann dadurch auch Methoden übers Interface auslösen und alle Clients benachrichtigen.
Nur bei der Freigabe gibts ein Problem. Wenn ich den self-Pointer in der Interfaceliste speichere wird der Referenz-Counter erhöht. Die Destroy-Routine (welche den Pointer in der Interfaceliste wieder freigibt) wird deshalb beim Beenden eines Clients nicht aufgerufen.
Das muss ich irgendwie anders lösen aber wie?

Tom

Zitat von Bernhard Geyer:
Das Schlagwort für Events vom Server zum Client ist die . Hierzu wird eine weitere (Event-)Schnitttelle definiert, welche jetzt vom Client implementiert wird um vom Server aufgerufen wird.

Dazu holst Du dir auf jedenfall mal das EventSinkImp-Tool von Binh Ly und am besten auch gleich das Buch von A Kosch über COM/DCOM/COM+ um auch die Probleme z.B. bezüglich Rechtevergabe zu verstehen.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Interfaceliste bei einem Auto-Objekt

  Alt 7. Jun 2005, 14:35
Zitat von tgoessi:
Genauso hab ich es gemacht.
Glaube ich nicht ganz. Ich hab sowas vor einigen Jahren gemacht und hatte keine Probleme mit Referenzzählung.
Ich denke mal du machst hier einige Fehler und hälst dich nicht an das "Kochrezept" von A. Kosch.

Kannst Du auch etwas relevanten Code posten. Evtl. auch im Entwickler-Forum nachfragen, denn dort ist A. Kosch aktiv.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
tgoessi

Registriert seit: 31. Mai 2005
34 Beiträge
 
Delphi 5 Enterprise
 
#5

Re: Interfaceliste bei einem Auto-Objekt

  Alt 7. Jun 2005, 15:05
Hallo

Hier etwas Code:
Delphi-Quellcode:
Var DispInterfaces : TInterfaceList; //als globale Variable, da der Serverprozess auf die Interfaces zugreifen muss

procedure TDisp.Initialize;
begin
  inherited Initialize;
  FConnectionPoints := TConnectionPoints.Create(Self); // für die Events
  if AutoFactory.EventTypeInfo <> nil then
    FConnectionPoint := FConnectionPoints.CreateConnectionPoint(
      AutoFactory.EventIID, ckSingle, EventConnect)
  else FConnectionPoint := nil;

  if not assigned (DispenserInterfaces) then
    DispenserInterfaces := TInterfaceList.Create;
  DispenserInterfaces.Add(self as IDispTriggerEvents);

  inc(IntfRefCount); // Zähler für Clients
end;

destructor TDisp.Destroy;
var
  i : byte;
begin
  if assigned (DispenserInterfaces) then
    DispenserInterfaces.Remove(self as IDispTriggerEvents);
  dec(IntfRefCount);
  if IntfRefCount = 0 then begin
    DispenserInterfaces.Free;
  end;
  inherited Destroy;
end;
Das IDispTriggerEvents ist ein privates Interface von TDisp bzw. IDisp. Damit greift der Server auf eine Interfaceroutine zu, welche das Event auslöst. Diese Routine sieht folgendermassen aus:
Delphi-Quellcode:
procedure TDisp.New_EventData(State, NumColls : byte);
begin
  FLastState := State;
  FLastNumColls := NumColls
  FEvents.OnNewData(State, NumColls);
end;
Der Grund für dies: Jeder Client kann die Daten des letzten Events abrufen, was seinerseits ein neues Event auslöst, das dann aber nur an diesen Client geschickt wird.
Die Routine dafür:
Delphi-Quellcode:
procedure TDisp.TriggerData;
begin
  FEvents.OnNewData(FLastState,FLastNumColls);
end;
Wenn der Server ein Event auslöst, geschieht das in einer Schleife:
Delphi-Quellcode:
procedure TServer.FireEvent;
var
  i : byte;
begin
  for i := 0 to DispInterfaces.Count-1 do
    (DispInterfaces.Item[i] as IDispTriggerEvents).New_EventData(FState,FColls);
end;
Man könnte nun natürlich die Variable DispInterfaces auch als interne Variable im TDisp-Objekt speichern und in der Routine New_EventData die Schleife machen.
Doch auch wenn man DispInterfaces objektintern speichert, geht der Referenzzähler beim Beenden eines Clients nicht auf 0 und die Destroy-Routine wird nicht aufgerufen.

Gruss
Tom




Zitat von Bernhard Geyer:
Zitat von tgoessi:
Genauso hab ich es gemacht.
Glaube ich nicht ganz. Ich hab sowas vor einigen Jahren gemacht und hatte keine Probleme mit Referenzzählung.
Ich denke mal du machst hier einige Fehler und hälst dich nicht an das "Kochrezept" von A. Kosch.

Kannst Du auch etwas relevanten Code posten. Evtl. auch im Entwickler-Forum nachfragen, denn dort ist A. Kosch aktiv.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz