AGB  ·  Datenschutz  ·  Impressum  







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

Supports verständnis problem

Ein Thema von EWeiss · begonnen am 30. Mai 2014 · letzter Beitrag vom 30. Mai 2014
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

Supports verständnis problem

  Alt 30. Mai 2014, 07:42
Ich erstelle ein Com Objekt auf diese weise.

Delphi-Quellcode:
function TWMPHelper.InitVis(VisGUID: TGuid; PresetIndex: Integer): Bool;
var
  ObjInstance : IUnknown;

begin
  Result := False;

    if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
      IUnknown, ObjInstance) = S_OK then
    begin
      // Versuch auf IWmpEffects zu casten. Bei einem Fehlschlag,
      // wird Nil zurück gegeben und die ObjInstance
      // unterstützt das Interface IWmpEffects nicht.
      _IWmpEffects := ObjInstance as IWMPEffects;

      if Assigned(_IWmpEffects) then

      // Versuch auf IWmpEffects2 zu casten. Bei einem Fehlschlag,
      // wird Nil zurück gegeben und die ObjInstance
      // unterstützt das Interface IWmpEffects2 nicht.
      if Supports(_IWmpEffects, IID_IWMPEffects2, _IWmpEffects2) then
        _IWmpEffects2 := ObjInstance as IWmpEffects2;

      // wird das Interface IWmpEffects2 unterstützt, brauchen
      // wir das Interface IWmpEffects nicht mehr.
      if Assigned(_IWmpEffects2) then
        _IWmpEffects := nil;

      // Erstes Preset setzen. Das muss sein da es ansonsten bei
      // einigen Visualisierungen zu einer AccessViolation Exception führt.
      SetCurrentPreset(PresetIndex);

      Result := True;
    end;

end;
Wenn ich auf das IWmpEffects2 caste funktioniert es auf verschiedener weise
warum das so ist da komme ich nicht hinter.

Supports(_IWmpEffects, IID_IWMPEffects2, _IWmpEffects2) funktioniert!

aber auch das!
Supports(_IWmpEffects, IID_IWMPEffects2, ObjInstance)

ObjInstance wäre in den fall dann IWmpEffects.

und das geht ebenfalls
Supports(_IWmpEffects, IID_IWMPEffects, ObjInstance) Was mache ich falsch?
Oder warum führen alle Aufrufe zum gleichen Ergebnis?

Sorry gehört zum gleichen Thema..

Kann man CoCreateInstance irgendwo freigeben ?
Denn die eine Visualisierung funktioniert nicht wenn ich nicht vorher CoUninitialize aufrufe.

EDIT:
Hab es nochmal korrigiert.

gruss

Geändert von EWeiss (30. Mai 2014 um 08:02 Uhr)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#2

AW: Supports verständnis problem

  Alt 30. Mai 2014, 08:26
Supports kann den Typ der Variablen nicht gegen den angegebene Interface-Typ prüfen.
Ansonsten verstehe ich nicht, wo das Problem liegt.

http://docwiki.embarcadero.com/Libra...Utils.Supports
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Supports verständnis problem

  Alt 30. Mai 2014, 08:31
Supports kann den Typ der Variablen nicht gegen den angegebene Interface-Typ prüfen.
Ansonsten verstehe ich nicht, wo das Problem liegt.

http://docwiki.embarcadero.com/Libra...Utils.Supports

Also wenn du schon verlinkst dann ist das die Antwort auf deine frage.
Zitat:
Mit Supports ermitteln Sie, ob das in Instance angegebene Objekt (oder das Interface) oder die im Parameter AClass angegebene Klasse das im Parameter IID festgelegte Interface unterstützt.

Wie du sehen kannst gebe ich unterschiedliche Interface an und trotzdem ist das Ergebnis immer gleich.
Warum ?

gruss

Geändert von EWeiss (30. Mai 2014 um 08:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Supports verständnis problem

  Alt 30. Mai 2014, 08:40
Du kannst das auch so schreiben (wird dann evtl. verständlicher)
Delphi-Quellcode:
function TWMPHelper.InitVis(VisGUID: TGuid; PresetIndex: Integer): Bool;
var
  ObjInstance : IUnknown;
begin
  Result := False;

    if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
      IUnknown, ObjInstance) = S_OK then
    begin
      // Versuch auf IWmpEffects zu casten. Bei einem Fehlschlag,
      // wird Nil zurück gegeben und die ObjInstance
      // unterstützt das Interface IWmpEffects nicht.

      if Supports( ObjInstance, IID_IWMPEffects, _IWmpEffects ) then

        // Versuch auf IWmpEffects2 zu casten. Bei einem Fehlschlag,
        // wird Nil zurück gegeben und die ObjInstance
        // unterstützt das Interface IWmpEffects2 nicht.

        if Supports( ObjInstance, IID_IWMPEffects2, _IWmpEffects2) then

          // wird das Interface IWmpEffects2 unterstützt, brauchen
          // wir das Interface IWmpEffects nicht mehr.

          _IWmpEffects := nil;

      // Erstes Preset setzen. Das muss sein da es ansonsten bei
      // einigen Visualisierungen zu einer AccessViolation Exception führt.
      SetCurrentPreset(PresetIndex);

      Result := True;
    end;

end;
oder auch so
Delphi-Quellcode:
function TWMPHelper.InitVis(VisGUID: TGuid; PresetIndex: Integer): Bool;
var
  ObjInstance : IUnknown;
begin
  Result := False;

    if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
      IUnknown, ObjInstance) = S_OK then
    begin

      // Versuch auf IWmpEffects2 zu casten. Bei einem Fehlschlag,
      // wird Nil zurück gegeben und die ObjInstance
      // unterstützt das Interface IWmpEffects2 nicht.

      if Supports( ObjInstance, IID_IWMPEffects2, _IWmpEffects2 ) then
        _IWmpEffects = nil
      else
        // Versuch auf IWmpEffects zu casten. Bei einem Fehlschlag,
        // wird Nil zurück gegeben und die ObjInstance
        // unterstützt das Interface IWmpEffects nicht.

        Supports( ObjInstance, IID_IWMPEffects, _IWmpEffects);

      // Erstes Preset setzen. Das muss sein da es ansonsten bei
      // einigen Visualisierungen zu einer AccessViolation Exception führt.
      SetCurrentPreset(PresetIndex);

      Result := True;
    end;

end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (30. Mai 2014 um 08:46 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Supports verständnis problem

  Alt 30. Mai 2014, 08:56
Danke.. Aber verstehe immer noch nicht warum alle vergleiche zum gleichen Ergebnis führen.
Was ist falsch und was richtig. Hmmm

In *.Net ist das so einfach und hier so kompliziert verstehen tut man das nicht so recht.

Code:
TryCast(ObjInstance, IWmpEffects)
wenn fertig dann
Code:
TryCast(ObjInstance, IWmpEffects2)
und gut ist.

gruss

Geändert von EWeiss (30. Mai 2014 um 09:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Supports verständnis problem

  Alt 30. Mai 2014, 09:17
Warum sollte das auch nicht gehen?
Delphi-Quellcode:
IWmpEffects = interface( IUnknown )
...
end;

IWmpEffects2 = interface( IWmpEffects )
...
end;

var
  ObjInstance : IUnknown;
  _IWmpEffects : IWmpEffects;
  _IWmpEffects2 : IWmpEffects2;

// Wenn die Referenz in _IWmpEffects das Interface IID_IWMPEffects2 unterstützt
// dann stelle eine Interface-Referenz in _IWmpEffects2, ansonsten NIL
Supports( _IWmpEffects, IID_IWMPEffects2, _IWmpEffects2 );

// Wenn die Referenz in _IWmpEffects das Interface IID_IWMPEffects2 unterstützt
// dann stelle eine Interface-Referenz in ObjInstance, ansonsten NIL
Supports( _IWmpEffects, IID_IWMPEffects2, ObjInstance );

// Wenn die Referenz in _IWmpEffects das Interface IID_IWMPEffects unterstützt
// dann stelle eine Interface-Referenz in ObjInstance, ansonsten NIL
Supports( _IWmpEffects, IID_IWMPEffects, ObjInstance );
es geht ja auch das einfach so
Delphi-Quellcode:
ObjInstance := _IWmpEffects;
// oder
ObjInstance := _IWmpEffects2;
Fraglich ist ja nur, welchen Sinn Supports( _IWmpEffects, IID_IWMPEffects2, ObjInstance ); haben kann. Mit ObjInstance habe ich ja nur die Möglichkeit auf IUnknown zuzugreifen und müsste schon wieder mit Supports prüfen/casten.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (30. Mai 2014 um 09:22 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Supports verständnis problem

  Alt 30. Mai 2014, 09:12
Var-Parameter müssen immer vom selben Typ sein, weswegen Supports so nicht funktionieren könnte (außer man hätte mit bissl Compilermagic nachgeholfen).

Also wurde der Var-Parameter typlos angelegt und intern wird "blind" auf IInterface gegastet, da nicht geprüft werden kann, was wirklich als Parameter reingegeben wurde.



Im Grunde bekommt man bei allem, was zufällig 4 Byte (8 bei Win64) groß ist, das Interface reingeschoben.
Und bei Kleinerem bekommt man eventuelle Zugriffsverletzungen, oder zumindestens einen Buffer-Overrun.

Fazit: Du mußt prüfen.

PS: Bei meinem aktuellen Projekt geh ich einen anderen/neueren Weg.
Es gibt da z.B. folgende Methoden und vorallem die Letzte ist Interessanter.
Delphi-Quellcode:
function SupportsIDEService(Service: TGUID): Boolean; inline;
function GetIDEService (Service: TGUID): IInterface; inline;
function TryGetIDEService (Service: TGUID; out Intf): Boolean; inline;
property IDEServices: IBorlandIDEServices read GetIDEServices;
function IDEService<I: IInterface>: I;
Dort wird dann vir RTTI die GUID ausgelesen und entsprechend verwendet.

Im Prinzip wäre auch sowas möglich, wie function Supports<I: IInterface>: Boolean; , aber da Delphi die Interfaces bai Übergabe an einen GUD-Parameter automatisch "konvertiert", lohnt sich das nicht.
Aber function Supports<I: IInterface>(var Intf: I): Boolean; müsste auch funktionieren.



Was macht TryCast?
[edit] Achso, das ist fast wie ein AS (DirectCast), nur ohne Exception.
Aber gibt es auch den "richtigen2 Interfacetyp als Result zurück?

[edit2] Es ist also etwas wie mein IDEService<I: IInterface>: I; , nur daß ich eine Exception werfe und die stattdessen ein INothing (in Delphi wohl besser ein nil) zurückgeben.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (30. Mai 2014 um 09:19 Uhr)
  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:25 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