Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi QueryInterface ausschließen (https://www.delphipraxis.net/198425-queryinterface-ausschliessen.html)

EWeiss 1. Nov 2018 08:49

QueryInterface ausschließen
 
Delphi-Quellcode:
TCustomSessionThread = class(TThread)
  //
end;

TSessionThread = class(TCustomSessionThread, IAudioSessionNotification)
der Compiler meckert weil
  • QueryInterface
  • _AddRef
  • _Release

in meiner Class nicht definiert ist.

Hier jedoch geht es auch ohne!
Delphi-Quellcode:
TCustomAudioVolume = class(TWinControl)
  //
end;

TAudioVolume = class(TCustomAudioVolume, IAudioSessionEvents, IMMNotificationClient,
  IAudioSessionNotification, IAudioEndpointVolumeCallback)
Ist doch wenn man vom TThread <> TWinControl mal absieht das gleiche.

Meine Frage also warum ?
Ich möchte diese in der TSessionThread Class nicht hinzufügen wenn es machbar ist.

gruss

TiGü 1. Nov 2018 09:09

AW: QueryInterface ausschließen
 
Klicke dich per Strg+Linke Maustaste doch mal durch die Vererbungskette und sage mir, wie die Vorfahren heißen.




Spoiler: TWincontrol -> TControl -> TComponent

TComponent implementiert die von IInterface/IUnknown geforderten Methoden QueryInterface, _AddRef und _Release.

Wenn du direkt schreiben willst
Delphi-Quellcode:
TSessionThread = class(TCustomSessionThread, IAudioSessionNotification)
, dann musst du alle Methoden von IAudioSessionNotification und seinen Vorfahren implementieren, also den "Vertrag" erfüllen.
Es reicht auch als Stub, d.h die Methoden können auch leer sein.

EWeiss 1. Nov 2018 09:16

AW: QueryInterface ausschließen
 
Zitat:

TComponent implementiert die von IInterface/IUnknown geforderten Methoden QueryInterface, _AddRef und _Release.
Das erklärt einiges.. Danke.

Zitat:

Es reicht auch als Stub, d.h die Methoden können auch leer sein.
Jo habe ich gemacht nur dann habe ich die Warnungen
Zitat:

[dcc64 Warnung] SessionThread.pas(535): W1035 Rückgabewert der Funktion 'TCustomSessionThread.QueryInterface' könnte undefiniert sein
Muss dann wohl für die Unit die Warnungen ausschalten..

gruss

TiGü 1. Nov 2018 09:25

AW: QueryInterface ausschließen
 
Zitat:

Zitat von EWeiss (Beitrag 1417213)
Jo habe ich gemacht nur dann habe ich die Warnungen
Zitat:

[dcc64 Warnung] SessionThread.pas(535): W1035 Rückgabewert der Funktion 'TCustomSessionThread.QueryInterface' könnte undefiniert sein
Muss dann wohl für die Unit die Warnungen ausschalten..

An ein
Delphi-Quellcode:
Result := S_OK
oder
Delphi-Quellcode:
Result := E_NOTIMPL
oder
Delphi-Quellcode:
Result := E_NOINTERFACE
- je nachdem welches Verhalten man implementieren will - hast du nicht gedacht?

mjustin 1. Nov 2018 09:35

AW: QueryInterface ausschließen
 
Zitat:

Zitat von TiGü (Beitrag 1417212)
Spoiler: TWincontrol -> TControl -> TComponent

TComponent implementiert die von IInterface/IUnknown geforderten Methoden QueryInterface, _AddRef und _Release.

Ein eventuell interessanter Unterschied:

- TComponent._Release gibt die Instanz nicht frei.
- TInterfacedObject._Release gibt die Instanz frei.

https://stackoverflow.com/questions/...nt-leak-memory

EWeiss 1. Nov 2018 09:39

AW: QueryInterface ausschließen
 
Zitat:

je nachdem welches Verhalten man implementieren will - hast du nicht gedacht?
Schon. Aber! Wie der Vorredner erkannt hat wird in dem Fall meine Anwendung nicht mehr beendet.

gruss

TiGü 1. Nov 2018 09:41

AW: QueryInterface ausschließen
 
Zitat:

Zitat von EWeiss (Beitrag 1417217)
Zitat:

je nachdem welches Verhalten man implementieren will - hast du nicht gedacht?
Schon. Aber! Wie der Vorredner erkannt hat wird in dem Fall meine Anwendung nicht mehr beendet.

gruss

Weil der Thread noch läuft. :roll:
Entweder implementierst du das Verhalten zum zerstören des Threads im _Release oder du machst es klassisch von außen mit DeinThread.Free, ggf. mit DeinThread.WaitFor und DeinThread.Terminate arbeiten.

EWeiss 1. Nov 2018 09:55

AW: QueryInterface ausschließen
 
Zitat:

Weil der Thread noch läuft.
Delphi-Quellcode:
      if Assigned(SessionThread) then
      begin
        SessionThread.EndThread;
        Sleep(100);
        SessionThread.Free;
      end;
Der läuft nicht bzw. wird beendet kann er aber nicht weil mein Thread beim _Released in dem Fall wie getestet E_NOTIMPL zurückgibt
und der RefCounter nicht 0 ist.

Wenn ich die Rückgaben nicht auswerte funktioniert alles.
Aber dann hab ich halt die Warnung.
Muss mal schau'n wie ich das jetzt mache.

EDIT:
Es sollte ja egal sein wo ich die Funktionen implementiere ob in TCustomSessionThread oder TSessionThread dieser erbt ja von TCustomSessionThread.
Delphi-Quellcode:
  TCustomSessionThread = class(TThread)
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: integer; stdcall;
    function _Release: integer; stdcall;
  end;

  TSessionThread = class(TCustomSessionThread, IAudioSessionNotification)
gruss

TiGü 1. Nov 2018 10:22

AW: QueryInterface ausschließen
 
Mach mal bitte so:

Delphi-Quellcode:
function TCustomSessionThread._AddRef: Integer;
begin
  Result := -1;
end;

function TCustomSessionThread._Release: Integer;
begin
  Result := -1;
end;

function TCustomSessionThread.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GetInterface(IID, Obj) then
    Result := S_OK
  else
    Result := E_NOINTERFACE;
end;
Und beim beenden deines Threads:
Delphi-Quellcode:
      if Assigned(SessionThread) then
      begin
        SessionThread.Terminate;
        SessionThread.WaitFor;
        SessionThread.Free;
      end;

EWeiss 1. Nov 2018 10:37

AW: QueryInterface ausschließen
 
Danke!
So scheint es zu funktionieren.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:40 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