Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi COM: Wie bekomme ich das Objekt hinter einem Interface (https://www.delphipraxis.net/108913-com-wie-bekomme-ich-das-objekt-hinter-einem-interface.html)

ulrich.b 21. Feb 2008 00:18


COM: Wie bekomme ich das Objekt hinter einem Interface
 
COM Server

Zum einen habe ich eine Daten Klasse

Delphi-Quellcode:
  TDaten = class(TAutoObject, IDaten)
  private
    FGekapselt: TGekapselt;

  protected
    function Get_A: Integer; safecall;
    procedure Set_A(Value: Integer); safecall;

    function Get_obj_ptr: Pointer; safecall;

  public
    property Gekapselt: TGekapselt read FGekapselt;

  end;
Und zum anderen eine Klasse mit einer Methode, die einen Pointer auf dieses Interface als Parameter hat

Delphi-Quellcode:
  TAndereKlasse = class(TAutoObject, IAndereKlasse)
  protected
    function DoSomething(const Daten: IDaten): Integer; safecall;
  end;

Nun möchte ich innerhalb von DoSomething nicht nur auf die Interface Member, sondern auf das Objekt dahinter (die TDaten Instanz) zugreifen (Bevor ihr wieder alle fragt warum: Um an gekapselte Daten ranzukommen, wie ichs mit dem public Property angedeutet hab).

Gibts da igendeine schöne möglichkeit, um an den Pointer ranzukommen??

Ich hab es nämlich so gelöst:

Delphi-Quellcode:
function TDaten.Get_obj_ptr: Pointer;
begin
  Result := Self;
end;
Zugriff auf die Instanz:

Delphi-Quellcode:
function TAndereKlasse.DoSomething(const Daten: IDaten): Integer;
var
  DatenInstanz: TDaten;
begin
  DatenInstanz := TDaten(Daten.obj_ptr);
end;
Ich exportiere über das Interface einfach eine Methode, die den Objektpointer nach außen liefert. Gibt es hierfür schönere Lösungen? Können durch meine Implementierungen Probleme entstehen?

Dezipaitor 21. Feb 2008 16:13

Re: COM: Wie bekomme ich das Objekt hinter einem Interface
 
Das hab ich mich auch schon gefragt. Normal baut man ja Methoden, die alle anderen Methoden der inneren Klasse nach aussen geben.

Man kann natürlich so, wie du auch den Pointer zur Klasse verwenden. Dann funktioniert das meiner Meinung aber nicht mehr bei out-of-process Situationen. Ich habs noch nicht ausprobiert, kann es daher nicht 100% wissen.

Sonst ausprobieren und mir mitteilen :D

sirius 21. Feb 2008 16:16

Re: COM: Wie bekomme ich das Objekt hinter einem Interface
 
Vielleicht solltest du mal hier schauen, was Bernhard Geyer unten geschrieben hat.

ulrich.b 22. Feb 2008 11:13

Re: COM: Wie bekomme ich das Objekt hinter einem Interface
 
Zitat:

Zitat von Dezipaitor
Dann funktioniert das meiner Meinung aber nicht mehr bei out-of-process Situationen. Ich habs noch nicht ausprobiert, kann es daher nicht 100% wissen.

Was meinst du mit out-of-process Situationen?

Bernhard Geyer 22. Feb 2008 11:26

Re: COM: Wie bekomme ich das Objekt hinter einem Interface
 
Zitat:

Zitat von ulrich.b
Zitat:

Zitat von Dezipaitor
Dann funktioniert das meiner Meinung aber nicht mehr bei out-of-process Situationen. Ich habs noch nicht ausprobiert, kann es daher nicht 100% wissen.

Was meinst du mit out-of-process Situationen?

D.h. das Interfaces kommt aus einem anderen Prozess (oder auch von anderem Rechner) und COM sorgdafür das du einen Proxy in deinem Adressraum vorgesetzt bekommst den COM für die umsetzung auf anderen Prozess/Rechner zu hilfe nimmt. Ein "normales" Delphi-Objekt wird diese Umsetzung nicht überleben.

Dezipaitor 22. Feb 2008 11:28

Re: COM: Wie bekomme ich das Objekt hinter einem Interface
 
Du kannst COM Objekte in einem eigenen Prozess (exe-Datei) bereitstellen. Das kann z.B. für Automation (Steuererung dieser Applikation) verwendet werden. D.h. alle COM Aufrufe müssen über Prozessgrenzen hinweg geführt werden. Dazu werden Methodenaufrufe in einem Stream gespeichert (d.h. der Stack) und dann über Netzwerk gesendet (auch lokal).
Dieses Kapseln wird Marshalling genannt. Das Problem dabei ist, dass alle Typen, die der Standardmarshaller nicht kennt, nicht übertragen werden können. Darunter sind dynamische Strukturen (=Zeiger + Datenlänge). Nur bei Out-Of-Process Situationen ist ein Marshaller erforderlich, da Zeiger über Prozessgrenzen nicht gültig sind. Bei In-Process ist das garkein Problem. Man kann auch Zeiger im COM Verpacken. Die Ziele der Zeiger sind ja innerhalb desselben Prozesses.
Leider geht diese Situation vermutlich auch schon nicht mehr, wenn COM Objekte in verschiedenen Apartments sich befinden.

Ich habe so ein Problem, wie oben beschrieben in dem anderen Thread geschildert.


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