AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen
Thema durchsuchen
Ansicht
Themen-Optionen

Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

Ein Thema von mika · begonnen am 12. Sep 2011 · letzter Beitrag vom 8. Aug 2012
Antwort Antwort
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#1

Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 12. Sep 2011, 12:35
Hallo Forum,

lang ists her das ich hier mal was gepostet habe Da ich aber jetzt wieder vermehrt mit Delphi arbeite würde ich gerne mal eine Frage stellen.

Ich habe eine Klasse geschrieben, die abgeleitet von TThread ist und ein Interface implementiert, so als Beispiel:
Code:
type
  TMeineKlasse = Class(TThread, IInterfaceMein)
  end;

  TZweiteKlasse = Class(TInterfacedObjekt, IInterfaceZwei)
  end;
Bei TZweiteKlasse gelingt folgender aufruf, bei TMeineKlasse leider nicht, woran kann es liegen?
Code:
var
  meinInterface: IInterfaceMein;
  zweiInterface: IInterfaceZwei;
begin
  meinInterface := TMeineKlasse.Create AS IInterfaceMein; // Operator ist auf Operand nicht anwendbar
  zweiInterface := TZweiteKlasse AS IInterfaceZwei; // Geht
end;
Gibt es irgendwas einfaches das ich vergessen habe? Oder liegt es daran das eine Klasse von TTHread abgeleitet wurde?

Mfg, Mika
:: don't Panic ::
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#2

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 12. Sep 2011, 12:47
Da das IInterfaceMein implizit von IInterface abgeleitet ist, gehören dazu natürlich auch Implementierungen der dort deklarierten Methoden - insbesondere QueryInterface! Da der Compiler schon viel eher meckern würde, wenn diese Methoden nicht in deiner TThread-Ableitung enthalten wären, denke ich daß du die auch tatsächlich implementiert hast.

Wenn du jetzt dem Compiler sagst, daß dein TThread-Abkömmling das IInterface tatsächlich implementiert, sollte es auch gehen:

TMeineKlasse = Class(TThread, IInterface, IInterfaceMein)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.374 Beiträge
 
Delphi 12 Athens
 
#3

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 12. Sep 2011, 13:03
Wenn du das IInterface selber einbindest, dann mußt du natürlich auch die Methoden dieses Interfaces selber implementieren,
aber dafür kannst'e dir auch einfach alles Nötige aus dem TInterfacedObject rauskopieren.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (12. Sep 2011 um 13:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#4

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 12. Sep 2011, 16:14
Hei,

danke erstmal für die Antworten. Die Methoden des Interfaces habe ich eingebunden Hier mal zur besseren Verständnis richtiger Code:

Das Problem ist das gleiche, nur das man das AUgenmerk auf TDeviceController legt.

Interfaces
Code:
type
  { Forwardeklarationen }
  IDeviceController = interface;
  IDeviceEntity = interface;

  { Interface unserer obersten Controllerklasse }
  ILineController = interface(IInterface)['{4096970D-4269-4626-B710-AF753D80D0BF}']
    { Initialisiert den Controller mit den gegebenen Daten }
    function Initialize(db: TAdsConnection; id: Integer): Boolean;
    { Finalisiert den Controller, entfernt alle Daten }
    function Finalize: Boolean;

    { Setzt die Genauigkeit der Protokollierung }
    function SetLoglevel(ll: Integer): Boolean;

    { Gibt die Datenbankverbindung zurueck die angegeben wurde }
    function GetDatabaseConnection: TAdsConnection;
    function GetDatabaseConfigurationKey: Integer;

    { Setzt die Callbackmethode die der Controller aufrufen soll }
    function SetCallbackMethod(cm: TCallbackMethod): Boolean;

    { Verarbeitet einen DeviceStatus und reicht ihn an den Callback weiter }
    function ProcessDeviceStatus(ds: TDeviceStatus): Boolean;

    { Gibt die Anzahl der DeviceController zurück }
    function GetDeviceControllerCount: Integer;
    { Gibt den Index des übergebenen DeviceControllers wieder }
    function GetDeviceControllerIndex(dc: IDeviceController): Integer;
    { Gibt den DeviceController des übergebenen Index wieder }
    function GetDeviceControllerByIndex(index: Integer): IDeviceController;

    { Fügt einen neuen DeviceController hinzu }
    function AddDeviceController(dc: IDeviceController): Boolean;
    { Entfernt den übergebenen DeviceController }
    function RemoveAllDeviceController: Boolean;
    function RemoveDeviceController(index: Integer): Boolean; overload;
    function RemoveDeviceController(dc: IDeviceController): Boolean; overload;

    { Startet den übergebenen DeviceController }
    function StartAllDeviceController: Boolean;
    function StartDeviceController(index: Integer): Boolean; overload;
    function StartDeviceController(dc: IDeviceController): Boolean; overload;
    { Stoppt den übergebenen DeviceController }
    function StopAllDeviceController: Boolean;
    function StopDeviceController(index: Integer): Boolean; overload;
    function StopDeviceController(dc: IDeviceController): Boolean; overload;
    { Aktiviert den übergebenen DeviceController, somit wird er bei der
      Abfrage der DeviceController mit einbezogen }
    function ActivateAllDeviceController: Boolean;
    function ActivateDeviceController(index: Integer): Boolean; overload;
    function ActivateDeviceController(dc: IDeviceController): Boolean; overload;
    { Deaktiviert den übergebenen DeviceController, somit wird er bei der
      Abfrage der DeviceController übersprungen }
    function DeactivateAllDeviceController: Boolean;
    function DeactivateDeviceController(index: Integer): Boolean; overload;
    function DeactivateDeviceController(dc: IDeviceController): Boolean; overload;
  end;

  { Interface unserer Controllerklasse für die einzelnen Verbindungen/Module }
  IDeviceController = interface(IInterface)['{0217D970-51CC-49AD-944E-E9B0B86C6C14}']
    { Initialisiert den Controller mit den gegebenen Daten }
    function Initialize(lc: ILineController; id: Integer): Boolean;
    { Finalisiert den Controller, entfernt alle Daten }
    function Finalize: Boolean;
   
    { Setzt die Genauigkeit der Protokollierung }
    function SetLoglevel(ll: Integer): Boolean;

    { Setzt den LineController dieses Objekts, wichtig um Daten weiterzugeben }
    function SetLineController(lc: ILineController): Boolean;
    { Gibt den LineController dieses Objektszurück }
    function GetLineController: ILineController;

    { Setzt die Verbindung dieses Controllers, also Comport oder TCP/IP }
    function SetConnection(cnnct: IPort): Boolean;
    { Ermittelt die Verbindung dieses Controllers }
    function GetConnection: IPort;
    { Oeffnet die Verbindung }
    function OpenConnection(ps: TPortSettings): Boolean;
    { Schliesst die Verbindung }
    function CloseConnection: Boolean;
    { Liest von der Verbindung }
    function ReadConnection: String; overload;
    function ReadConnection(ByteCount: Integer): String; overload;
    { Schreibt auf die Verbindung }
    function WriteConnection(Text: String): Boolean;

    { Aktiviert den Controller, heisst er soll arbeiten falls gefragt }
    function Activate: Boolean;
    { Deaktiviert den Controller, Controller arbeitet nicht }
    function Deactivate: Boolean;

    { Startet die Abfrage der einzelnen Module die angeschlossen sind }
    function Start: Boolean;
    { Beendet die Abfrage der einzelnen Module die angeschlossen sind }
    function Stop: Boolean;

    { Gibt die Anzahl der angeschlossenen DeviceEntities zurück }
    function GetDeviceEntityCount: Integer;
    { Gibt den Index des übergebenen DeviceEntity wieder }
    function GetDeviceEntityIndex(de: IDeviceEntity): Integer;
    { Gibt das DeviceEntity des übergebenen Index wieder }
    function GetDeviceEntityByIndex(index: Integer): IDeviceEntity;

    { Fügt ein neues DeviceEntity hinzu }
    function AddDeviceEntity(de: IDeviceEntity): Boolean;
    { Entfernt das übergebene DeviceEntity }
    function RemoveAllDeviceEntitites: Boolean;
    function RemoveDeviceEntity(index: Integer): Boolean; overload;
    function RemoveDeviceEntity(de: IDeviceEntity): Boolean; overload;

    { Aktiviert das übergebenen DeviceEntity, somit wird es bei der
      Abfrage der DeviceEntities mit einbezogen }
    function ActivateAllDeviceEntities: Boolean;
    function ActivateDeviceEntity(index: Integer): Boolean; overload;
    function ActivateDeviceEntity(de: IDeviceEntity): Boolean; overload;
    { Dektiviert das übergebenen DeviceEntity, somit wird es bei der
      Abfrage der DeviceEntities ausgelassen }
    function DeactivateAllDeviceEntities: Boolean;
    function DeactivateDeviceEntity(index: Integer): Boolean; overload;
    function DeactivateDeviceEntity(de: IDeviceEntity): Boolean; overload;
  end;

  IDeviceEntity = interface(IInterface)['{E7803FED-19E9-462C-9289-2165E0464F53}']
    { Initialisiert den Controller mit den gegebenen Daten }
    function Initialize(lc: ILineController; dc: IDeviceController; id: Integer): Boolean;
    { Finalisiert den Controller, entfernt alle Daten }
    function Finalize: Boolean;

    { Setzt die Genauigkeit der Protokollierung }
    function SetLoglevel(ll: Integer): Boolean;

    { Setzt den LineController dieses Objekts, wichtig um Daten weiterzugeben }
    function SetLineController(lc: ILineController): Boolean;
    { Setzt den DeviceController dieses Objekts, wichtig um Daten weiterzugeben }
    function SetDeviceController(dc: IDeviceController): Boolean;
    { Gibt den LineController dieses Objekts wieder }
    function GetLineController: ILineController;
    { Gibt den DeviceController dieses Objekts wieder }
    function GetDeviceController: IDeviceController;

    { Aktiviert das modul, heisst er soll arbeiten falls gefragt }
    function Activate: Boolean;
    { Deaktiviert das Modul, Modul arbeitet nicht }
    function Deactivate: Boolean;

    { Liest den aktuellen Gerätestatus aus }
    function GetDeviceStatus: TDeviceStatus;
    { Setzt den aktuellen Gerätestatus. }
    function SetDeviceStatus(ds: TDeviceStatus): Boolean;

    { Setzt das Relais auf den angegebenen Status, falls vorhanden }
    function SetRelaisState(ns: Boolean): Boolean;

    { Schreibt den gegebenen Text auf das Display, falls vorhanden }
    function SetDisplayText(nt: String): Boolean;

    { Hat das Geraet die angegebene Eigenschaft? }
    function IsRfidModule: Boolean;
    function IsDisplayModule: Boolean;
    function IsRelaisModule: Boolean;
    function IsScannerModule: Boolean;
    function IsNumpadModule: Boolean;
  end;
TLineController
Code:
  TLineController = class (TInterfacedObject, ILineController)
  private
    // Logger dieser Klasse
    Logfile: TFCSLogging;
    // Die Verbindung zu unserer Datenbank
    DBConnection: TAdsConnection;
    // Die CallbackMethode die vom Aufrufer gesetzt werden kann
    CallbackMethod: TCallbackMethod;
    // Konfigurationsschluessel in der Datenbank
    ConfigurationKey: Integer;
    // Die Liste mit unseren DeviceControllern
    DeviceControllers: TInterfaceList;

    // Der Titel dieses LineControllers
    Titel: String;

    // Legt die zu dieser Konfiguration gehörenden Unterobjekte an
    function InitializeComponents: Boolean;
    // Erstellt einen Thread der die CallbackMethode ausfuehrt falls angegeben
    function ExecuteCallback(ds: TDeviceStatus): Boolean;
    // Speichert einen Gerätestatus in der Datenbank
    function PushDeviceStatusToDatabase(ds: TDeviceStatus): Boolean;

  public
    // Standardkonstruktor dieser Klasse
    constructor Create;
    // Standarddestruktor dieser Klasse
    destructor Destroy; reintroduce;

    // Aus dem Interface geerbte Methoden
    function Initialize(db: TAdsConnection; id: Integer): Boolean;
    function Finalize: Boolean;

    function SetLoglevel(ll: Integer): Boolean;

    function GetDatabaseConnection: TAdsConnection;
    function GetDatabaseConfigurationKey: Integer;

    function SetCallbackMethod(cm: TCallbackMethod): Boolean;

    function ProcessDeviceStatus(ds: TDeviceStatus): Boolean;

    function GetDeviceControllerCount: Integer;
    function GetDeviceControllerIndex(dc: IDeviceController): Integer;
    function GetDeviceControllerByIndex(index: Integer): IDeviceController;

    function AddDeviceController(dc: IDeviceController): Boolean;

    function RemoveAllDeviceController: Boolean;
    function RemoveDeviceController(index: Integer): Boolean; overload;
    function RemoveDeviceController(dc: IDeviceController): Boolean; overload;

    function StartAllDeviceController: Boolean;
    function StartDeviceController(index: Integer): Boolean; overload;
    function StartDeviceController(dc: IDeviceController): Boolean; overload;
   
    function StopAllDeviceController: Boolean;
    function StopDeviceController(index: Integer): Boolean; overload;
    function StopDeviceController(dc: IDeviceController): Boolean; overload;

    function ActivateAllDeviceController: Boolean;
    function ActivateDeviceController(index: Integer): Boolean; overload;
    function ActivateDeviceController(dc: IDeviceController): Boolean; overload;

    function DeactivateAllDeviceController: Boolean;
    function DeactivateDeviceController(index: Integer): Boolean; overload;
    function DeactivateDeviceController(dc: IDeviceController): Boolean; overload;
  end;
TDeviceController
Code:
type
  TDeviceController = class (TThread, IDeviceController)
  private
    // Referenzzaehler dieses InterfacedObjekts
    FRefCount: Integer;
    // Logger dieser Klasse
    Logfile: TFCSLogging;
    // Konfigurationsschluessel in der Datenbank
    ConfigurationKey: Integer;
    // LineController dem dieser DeviceController untergeordnet ist
    LineController: ILineController;
    // Verbindung die dieser DeviceController bereitstellt
    Port: IPort;
    // Die Liste mit unseren DeviceEntities
    DeviceEntities: TInterfaceList;

    // Der Titel dieses LineControllers
    Titel: String;
    // Ist der Controller aktiv? Sollen Geräte abgefragt werden?
    Aktiv: Boolean;
    // Zeit in Millisekunden zwischen zwei Abfragen
    DelayMSecs: Integer;

    // Methoden die Klassen benoetigen die ein Interface implementieren
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;

    // Legt die zu dieser Konfiguration gehörenden Unterobjekte an
    function InitializeComponents: Boolean;

  protected
    procedure Execute; override;

  public
    property RefCount: Integer read FRefCount;
    // Standardkonstruktor dieser Klasse
    constructor Create; reintroduce;
    // Standarddestruktor dieser Klasse
    destructor Destroy; reintroduce;

    // Aus dem Interface geerbte Methoden
    function Initialize(lc: ILineController; id: Integer): Boolean;
    function Finalize: Boolean;

    function SetLoglevel(ll: Integer): Boolean;

    function SetLineController(lc: ILineController): Boolean;
    function GetLineController: ILineController;

    function SetConnection(cnnct: IPort): Boolean;
    function GetConnection: IPort;

    function OpenConnection(ps: TPortSettings): Boolean;
    function CloseConnection: Boolean;
    function ReadConnection: String; overload;
    function ReadConnection(ByteCount: Integer): String; overload;
    function WriteConnection(Text: String): Boolean;

    function Activate: Boolean;
    function Deactivate: Boolean;

    function Start: Boolean;
    function Stop: Boolean;

    function GetDeviceEntityCount: Integer;
    function GetDeviceEntityIndex(de: IDeviceEntity): Integer;
    function GetDeviceEntityByIndex(index: Integer): IDeviceEntity;

    function AddDeviceEntity(de: IDeviceEntity): Boolean;

    function RemoveAllDeviceEntitites: Boolean;
    function RemoveDeviceEntity(index: Integer): Boolean; overload;
    function RemoveDeviceEntity(de: IDeviceEntity): Boolean; overload;

    function ActivateAllDeviceEntities: Boolean;
    function ActivateDeviceEntity(index: Integer): Boolean; overload;
    function ActivateDeviceEntity(de: IDeviceEntity): Boolean; overload;

    function DeactivateAllDeviceEntities: Boolean;
    function DeactivateDeviceEntity(index: Integer): Boolean; overload;
    function DeactivateDeviceEntity(de: IDeviceEntity): Boolean; overload;
  end;
TDeviceEntity, IPort und so weiter sollten in dem Kontext keine Rolle spielen denk ich mal...
JKetzt möchte ich halt in einer Methode von TLineController folgendes machen können:

Code:
var
  meinDevice: IDeviceController;
begin
  meinDevice := TDeviceController.Create AS IDeviceController;
end;
aber das geht wie gesagt nicht und ich könnte mir das nur erklären weil DeviceController halt von TThread abgeleitet ist.
:: don't Panic ::

Geändert von mika (12. Sep 2011 um 16:16 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#5

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 12. Sep 2011, 16:21
Ich wiederhole:

type
TDeviceController = class (TThread, IInterface, IDeviceController)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#6

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 12. Sep 2011, 23:07
Danke für den Tipp Herr Raabe, ich werd das morgen mal ausprobieren.

Ich hab gedacht da IDeviceController schon IInterface implementiert, hat TDeviceController das dadurch auch. Ich war mir nicht sicher ob das bei den Interfaces in Delphi mitvererbt wird.

Deswegen hatte ich auch folgende Zeilen in TDeviceController aufgenommen.
Code:
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;

Schönen Abend noch.
:: don't Panic ::
  Mit Zitat antworten Zitat
fuchsle

Registriert seit: 22. Jul 2011
Ort: Heilbronn
35 Beiträge
 
Delphi XE3 Professional
 
#7

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 8. Aug 2012, 09:02
Da das IInterfaceMein implizit von IInterface abgeleitet ist, gehören dazu natürlich auch Implementierungen der dort deklarierten Methoden - insbesondere QueryInterface! Da der Compiler schon viel eher meckern würde, wenn diese Methoden nicht in deiner TThread-Ableitung enthalten wären, denke ich daß du die auch tatsächlich implementiert hast.

Wenn du jetzt dem Compiler sagst, daß dein TThread-Abkömmling das IInterface tatsächlich implementiert, sollte es auch gehen:

TMeineKlasse = Class(TThread, IInterface, IInterfaceMein)
Hallo,

ich bin über diesen Beitrag gestoßen, da ich ein Interface in einem Thread nutzen möchte.
Dazu habe ich versucht das oben zitierte umzusetzen.

Wie folgt sieht mein Beispiel aus:
Delphi-Quellcode:
unit Unit2;

interface

uses
  Classes;

type
  IMyInterface = Interface(IInterface)
    procedure setstate;
    function getstate(): Boolean;
    property State: Boolean read getstate write setstate;
  End;

  TMyThread = class(TThread, IInterface, IMyInterface)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  end;

implementation
Jedoch kommt es zu folgenden Meldungen:
[DCC Fehler] Unit2.pas(15): E2003 Undeklarierter Bezeichner: 'QueryInterface'
[DCC Fehler] Unit2.pas(15): E2003 Undeklarierter Bezeichner: '_AddRef'
[DCC Fehler] Unit2.pas(15): E2003 Undeklarierter Bezeichner: '_Release'

Muss ich diese Methoden doch selbst implementieren?
Bin davon ausgegangen, dass diese vererbt werden.

Vielen Dank.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.374 Beiträge
 
Delphi 12 Athens
 
#8

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 8. Aug 2012, 09:10
Muss ich diese Methoden doch selbst implementieren?
Bin davon ausgegangen, dass diese vererbt werden.
Natürlich mußt du das.

Das Interface selber erbt diese Grundfunktionen, aber woher soll die Klasse diese denn kennen?

TInterfacedObjekt oder TComponent als Vorfahre und man könnte diese erben, aber TThread/TObject kennt das eben nicht.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#9

AW: Klasse von TTHread ableiten und Interface implementieren, Objekt erstellen

  Alt 8. Aug 2012, 10:43
Muss ich diese Methoden doch selbst implementieren?
Bin davon ausgegangen, dass diese vererbt werden.
Ein Interface implementiert nichts, sondern sagt nur, was eine Implementierung mindestens können muss.
  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 04:04 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-2025 by Thomas Breitkreuz