AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Verweis auf Interface-Instanz weitergeben - ist das erlaubt?
Thema durchsuchen
Ansicht
Themen-Optionen

Verweis auf Interface-Instanz weitergeben - ist das erlaubt?

Ein Thema von Bodenseematze · begonnen am 27. Feb 2024 · letzter Beitrag vom 1. Mär 2024
 
Bodenseematze

Registriert seit: 10. Jul 2023
50 Beiträge
 
#1

Verweis auf Interface-Instanz weitergeben - ist das erlaubt?

  Alt 27. Feb 2024, 09:17
Hallo,

ich bin mir aktuell etwas unsicher, was die Speicherung und Weitergabe von Interface-Verweisen anbelangt.
Ist das erlaubt oder wird mir hier bei der Weiterreichung der "Zeiger" kaputt gemacht wg. Referenzzählung?

Ich versuche mal, das ganze hier (stark vereinfacht) darzustellen...

Ich habe Schnittstellendefinitionen, z.B.:
Delphi-Quellcode:
ITestGet = interface[ '{725D0235-8604-4E26-88E4-29223A3E6EB1}' ]
   function GetTestName() : String;
   property TestName : String
                                    read GetTestName;
end;


ITestSet = interface( ITestGet )[ '{2F54CC2F-70A8-4621-99C6-2B1CD5AE079F}' ]
   procedure SetTestName( const sName_ : String );
   property TestName : String
                                    write SetTestName;
end;


ITestImpl = interface( ITestGet )[ '{1C48CB92-1DA9-452E-9921-9B43A598715A}' ]
   procedure SetIfTestImpl( ifTestImpl_ : ITestImpl );
   function GetIfTestImpl() : ITestImpl;

   property IfTestImpl : ITestImpl
                                    read GetIfTestImpl
                                    write SetIfTestImpl;
end;

Dann habe ich folgende Klassen:
Delphi-Quellcode:
TMyBaseForm = class( TForm )
public
   constructor Create( owner_ : TComponent ); override;
   constructor CreateMe( owner_ : TComponent ); virtual;

   procedure SetIfTestImpl( ifTestImpl_ : ITestImpl ); virtual;
   function GetIfTestImpl() : ITestImpl; virtual;

   function GetIsIfTestImplSelf() : Boolean; virtual;

   property IfTestImpl : ITestImpl
                                    read GetIfTestImpl
                                    write SetIfTestImpl;

   property IsIfTestImplSelf : Boolean
                                    read GetIsIfTestImplSelf;

private
   _ifTestImpl : ITestImpl;
end;


//***************************************************************************
TMyOtherForm = class( TMyBaseForm )
published
   pbTest : TButton;


public
   constructor CreateMe( owner_ : TComponent ); override;
end;


//***************************************************************************
TMyMainBaseForm = class( TMyBaseForm, ITestImpl )
public
   constructor CreateMe( owner_ : TComponent ); override;

   procedure SetIfTestImpl( ifTestImpl_ : ITestImpl ); override;

   function GetTestName() : String; virtual;

   property TestName : String
                                    read GetTestName;
end;


//***************************************************************************
TMyMainForm = class( TMyMainBaseForm, ITestSet )
public
   constructor CreateMe( owner_ : TComponent ); override;

   function GetTestName() : String; override;
   procedure SetTestName( const sName_ : String ); virtual;

   property TestName : String
                                    read GetTestName
                                    write SetTestName;

private
   _sTestName : String;
end;

Hier die Implementierungen:
Delphi-Quellcode:
constructor TMyBaseForm.Create(
                                    owner_ : TComponent );
begin
   CreateMe( owner_ );
end;


constructor TMyBaseForm.CreateMe( owner_ : TComponent );
var
   ifTestImplMy : ITestImpl;
begin
   _ifTestImpl := nil;
   if ( Assigned(owner_) and Supports(owner_, ITestImpl, ifTestImplMy) ) then begin
      SetIfTestImpl( ifTestImplMy );
   end;
end;


procedure TMyBaseForm.SetIfTestImpl( ifTestImpl_ : ITestImpl );
begin
   _ifTestImpl := ifTestImpl_;
end;


function TMyBaseForm.GetIfTestImpl() : ITestImpl;
begin
  Result := _ifTestImpl;
end;


function TMyBaseForm.GetIsIfTestImplSelf() : Boolean;
var
  ifTestImplMy : ITestImpl;
begin
   Result := false;
   if ( Assigned(_ifTestImpl) ) then begin
      if ( Supports(Self, ITestImpl, ifTestImplMy) ) then begin
         if ( _ifTestImpl = ifTestImplMy ) then begin
            Result := true;
         end;
      end;
   end;
end;


//***************************************************************************
constructor TMyOtherForm.CreateMe( owner_ : TComponent );
var
   ifTestImplMy : ITestImpl;
begin
   inherited CreateMe( owner_ );

   pbTest := TButton.Create( Self );
   pbTest.Caption := 'Unknown';
   ifTestImplMy := IfTestImpl;
   if ( Assigned(ifTestImplMy) ) then begin
      pbTest.Caption := ifTestImplMy.TestName;
   end;
end;


//***************************************************************************
constructor TMyMainBaseForm.CreateMe( owner_ : TComponent );
var
   ifTestImplMy : ITestImpl;
begin
   inherited CreateMe( owner_ );
   ifTestImplMy := GetIfTestImpl();
   if ( NOT Assigned(ifTestImplMy) ) then begin
      SetIfTestImpl( nil );
   end;
end;


procedure TMyMainBaseForm.SetIfTestImpl( ifTestImpl_ : ITestImpl );
var
   ifTestImplMy : ITestImpl;
begin
   ifTestImplMy := ifTestImpl_;
   if ( NOT Assigned(ifTestImplMy) ) then begin
      Supports( Self, ITestImpl, ifTestImplMy );
   end;
   inherited SetIfTestImpl( ifTestImplMy );
end;


function TMyMainBaseForm.GetTestName() : String;
var
   ifTestImplMy : ITestImpl;
begin
   Result := EmptyStr;
   ifTestImplMy := GetIfTestImpl();
   if ( Assigned(ifTestImplMy) then begin
      if ( IsIfTestImplSelf ) then begin
         Result := Format( '%s.%s', [Classname, Name] );
      end
      else begin
         Result := ifTestImplMy.GetTestName();
      end;
   end;
end;


//***************************************************************************
constructor TMyMainForm.CreateMe( owner_ : TComponent );
begin
   inherited CreateMe( owner_ );
   _sTestName := EmptyStr;
end;


function TMyMainForm.GetTestName() : String;
begin
    if ( Length(_sTestName) > 0 ) then begin
       Result := _sTestName;
    end
    else begin
       Result := inherited GetTestName();
    end;
end;


procedure TMyMainForm.SetTestName( const sName_ : String );
begin
   _sTestName := sName_;
end;
In der Art wie TMyOtherForm gibt es ganz viele Klassen, so wie TMyMainForm gibt es normalerweise nur eine; wenn die MyOtherForm-Klassen instanziert werden, existiert die Instanz von TMyMainForm bereits und sie erhalten als Owner diese Instanz.

Ich habe jetzt das Problem, dass manchmal bei den Aufrufen von GetIfTestImpl bzw. dem Property IfTestImpl als Ergebnis nil zurück kommt, obwohl die interne Klassenvariable _ifTestImpl gesetzt ist.
Ich habe da bereits in der Methode eine Log-Ausgabe der Art Format( '%8.8X', [Integer(_ifTestImpl)] ) die zeigt eine Adresse an - wenn ich das ganze dann nach zurückkehren der Methode im Aufrufer mit dem zugewiesenen Ergebnis mache, kommt 0 als Ergebnis
--> deswegen meine Frage: ist es erlaubt, Interface-Zeiger in einer Klassenvariablen zu speichern und "herumzureichen"?

(das ganze wie immer bei mir für Delphi7 )
  Mit Zitat antworten Zitat
 

 

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 23:03 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