Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zurück geliefertes Objekt "halten" (https://www.delphipraxis.net/64334-zurueck-geliefertes-objekt-halten.html)

LaNtHaN 2. Mär 2006 10:26


Zurück geliefertes Objekt "halten"
 
Hallo zusammen...

Im Moment versuche ich mich an einem dll, mit welchem ich auf einem DXS-Server bestimmte Tags(Variablen) auslesen oder erstellen kann.
Beim erstellen eines neuen Tags liefert es mir Anscheinend ein Objekt zurück, welches ich halten muss, da ansonsten die erstellte Variable wieder stirbt.

Das DLL ist in etwa wie folgt aufgebaut:
DXSTAGSLib
->ITagsEvents(DispInterface)
->ITagEvents(DispInterface)
->Tags(CoClass)
->ITags(Interface)
-->Item(property)
-->CreateBool(method)
-->usw.
->Tag(CoClass)
->ITag(Interface)
-->Value(property lesen)
-->Value(property setzen)

Der Text, welcher hinter CreateBool steht sieht so aus:
Delphi-Quellcode:
[
id(0x00000001),
helpstring("method CreateBool")
]
HRESULT _stdcall CreateBool([in] VARIANT tagName, [out, retval] VARIANT * pTag );
Dies ist der Code, welcher solch ein Tag mit dem Namen "DXSTest" erstellt. Das erstellte Tag verschwindet jedoch gleich wieder.
Delphi-Quellcode:
var
  Form1: TForm1;
  dxs: Variant;

implementation

{$R *.DFM}


procedure TForm1.FormCreate(Sender: TObject);
begin
     dxs := CreateOleObject('MicroInnovation.DXS.Tags');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  dxs.CreateBool('DXSTEST');
end;
Noch ein Kommentar vom Support, welche mir jedoch nicht ganz klar macht wie ich sowas in Delphi nun lösen kann.

Zitat:

Wenn du ein CreateBool machst, kriegst du ein Objekt zurück. Das Objekt "stirbt" aber gleich wieder wenn es nicht verwendet wird. Die Annahme ist nun, dass du das Objekt nicht hälst und dieses Bool objekt somit nur sehr kurzlebig sprich im monitor schon gar nicht sichtbar ist.
Wir haben ja da im Excel diese Collection von Objekten gemacht, die ständig existierte, also die Objekte hielt und somit diese im DXS angemeldet blieben.
Weitere Frage die aufgetaucht ist:

Die CoClass Tag ist kein direkt erzeugbares Objekt.
Wie greife ich auf solch eine CoClass zu?

Der Text, welcher hinter CoClass Tag steckt:

Delphi-Quellcode:
[
  uuid(BE55C0E2-F111-4B5D-84BC-73DDCFFFE484),
  helpstring("MicroInnovation.DXS.Tag Class"),
  noncreatable
]
coclass Tag
{
  [default] interface ITag;
  [default, source] dispinterface _ITagEvents;
};
Vielen Dank für eure Hilfe.

shmia 2. Mär 2006 11:03

Re: Zurück geliefertes Objekt "halten"
 
Wenn du ein IDispatch - Interface verpackt in einem Variant (genauer OleVariant) bekommst,
musst du dieses in einer Variablen ablegen:

Delphi-Quellcode:
TForm1 = class(TForm)
....

private
   Fdxstest : OleVariant;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Interface holen und merken
  Fdxstest := dxs.CreateBool('DXSTEST');
  // dadurch wird der Referenzzähler um eins erhöht
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  // Interface freigeben
  Fdxstest := Unassigned;
  // dadurch wird der Referenzzähler um eins erniedrigt
  // wenn das Formular freigegeben wird, wird "Fdxstest" auch freigegeben
  // man muss also OleVariant nicht unbedingt "löschen"
end;

LaNtHaN 2. Mär 2006 12:18

Re: Zurück geliefertes Objekt "halten"
 
Vielen Dank für die Hilfe.
Der erste Teil hat funktioniert. Im Moment stellt sich mir nur noch die Frage zu folgendem Teil.

Zitat:

Zitat von LaNtHaN
Weitere Frage die aufgetaucht ist:

Die CoClass Tag ist kein direkt erzeugbares Objekt.
Wie greife ich auf solch eine CoClass zu?

Der Text, welcher hinter CoClass Tag steckt:

Delphi-Quellcode:
[
  uuid(BE55C0E2-F111-4B5D-84BC-73DDCFFFE484),
  helpstring("MicroInnovation.DXS.Tag Class"),
  noncreatable
]
coclass Tag
{
  [default] interface ITag;
  [default, source] dispinterface _ITagEvents;
};
Vielen Dank für eure Hilfe.


shmia 2. Mär 2006 12:40

Re: Zurück geliefertes Objekt "halten"
 
Zitat:

Zitat von LaNtHaN
Der erste Teil hat funktioniert. Im Moment stellt sich mir nur noch die Frage zu folgendem Teil.
Zitat:

Zitat von LaNtHaN
Weitere Frage die aufgetaucht ist:

Die CoClass Tag ist kein direkt erzeugbares Objekt.
Wie greife ich auf solch eine CoClass zu?


Nicht DU erzeugst das Objekt, sondern du holst dir ein IDispatch-Interface ab, mit dem du arbeiten darfst.
Also musst du in der TLB-Datei nachschauen, welche Methoden und Properties vom Interface ITag implementiert werden. Dann gibt es 2 Möglichkeiten:

Delphi-Quellcode:
// über Dispatch-Schnittstelle arbeiten (einfach, aber etwas langsam)
begin
  Fdxstest.IrgendEineMethode;
  Fdxstest.EineZweiteMethode(1000);
end;

// mit früher Bindung arbeiten (schnellerer Code, etwas aufwendiger)
var
   atag : ITag;
begin
   // Dispatch-Iterface aus Fdxstest lesen und in das passende Interface umwandeln
   atag := IDispatch(Fdxstest) as ITag;
   
   // ab hier funktioniert dann auch die Syntax-Prüfung von Delphi
   atag.IrgendEineMethode;
   atag.EineZweiteMethode(1000);
   
   // die Interface-Variable atag wird von Delphi automatisch entsorgt
   // man braucht nichts tun
end;

LaNtHaN 3. Mär 2006 08:14

Re: Zurück geliefertes Objekt "halten"
 
Danke vielmals...
Auch diese funktioniert nun.

Bei mir ist noch eine weitere Frage dazu aufgetaucht.

Im DLL gibt es nocht ein DispInterface mit dem Namen _ITagsEvents, welches mir bei einer Änderung eine Procedure aufrufen soll.
Ich habe dies wiefolgt gelöst:


Delphi-Quellcode:
_ITagsEvents = dispinterface
    ['{4A0ABBB6-EC00-4E3A-861A-6BD0DACCA172}']
    procedure ValueChanged(name, newValue: OleVariant); dispid 1;
end;


var
  Form1: TForm1;
  dxs: OleVariant;

implementation

{$R *.DFM}


procedure ValueChanged(name, newValue: Variant);
begin
     showmessage('Change');
end;
Der Text im DLL welcher dahinter steckt sieht so aus:

Delphi-Quellcode:
[
  uuid(4A0ABBB6-EC00-4E3A-861A-6BD0DACCA172),
  helpstring("_ITagsEvents Interface")
]
 dispinterface _ITagsEvents
{
  properties:
  methods:
  [
  id(0x00000001),
  helpstring("method ValueChanged")
  ]
  HRESULT ValueChanged(VARIANT name, VARIANT newValue );
};
Das ganze funktioniert jedoch noch nicht so recht, zumindest komme ich nicht in die Procedure.
Da ich zum erstenmal mit DispInterface arbeite ist mir nicht so ganz klar was ich falsch mache...

Vielen Dank im Voraus...

shmia 3. Mär 2006 10:57

Re: Zurück geliefertes Objekt "halten"
 
Zitat:

Zitat von LaNtHaN
Im DLL gibt es nocht ein DispInterface mit dem Namen _ITagsEvents, welches mir bei einer Änderung eine Procedure aufrufen soll.

Hier hast du einen Schwachpunkt von Delphi entdeckt.
Wenn du ein Event über COM empfangen möchtest, dann musst du entweder beim Import der TLB einen
Komponentenwrapper erzeugen lassen oder das Interface _ITagsEvents selbst implementieren (also eine neue Klasse schreiben)
und über weitere komplizierte Schritte das Ganze zum Laufen bringen.

weitergehende Info:
http://www.techvanguards.com/com/con...ventbasics.asp

LaNtHaN 3. Mär 2006 12:40

Re: Zurück geliefertes Objekt "halten"
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt mal die TLB importiert und dort einen Wrapper generiert...
Daraus hab ich ein pas-File erhalten. Irgendwie werde ich nun nicht ganz schlau daraus wie ich dieses nun richtig implementiere, damit das dispInterface funktioniert.

shmia 3. Mär 2006 16:50

Re: Zurück geliefertes Objekt "halten"
 
Zitat:

Zitat von LaNtHaN
Ich habe jetzt mal die TLB importiert und dort einen Wrapper generiert...
Daraus hab ich ein pas-File erhalten. Irgendwie werde ich nun nicht ganz schlau daraus wie ich dieses nun richtig implementiere, damit das dispInterface funktioniert.

Erzeuge ein Objekt der Klasse TTags.
TTags kapselt das Interface ITags und _ITagsEvents.
Delphi-Quellcode:
FTagsObj := TTags.Create(self);
FTagsObj.OnValueChanged := self.ValueChangedHandler;
FTagsObj.Connect; // Verbindung zum COM/DCOM Objekt herstellen

// dieses Connect ersetzt dann die Zeile
// dxs := CreateOleObject('MicroInnovation.DXS.Tags');
// statt dxs verwendest du dann FTagsObj.DefaultInterface

....
procedure TForm1.ValueChangedHandler(ASender: TObject; name: OleVariant; newValue: OleVariant);
begin
   ShowMessage('das Dingens <'+name '> wurde geändert.');
end;
PS: schönes Wochenende, ich bin weg

LaNtHaN 7. Mär 2006 13:13

Re: Zurück geliefertes Objekt "halten"
 
Danke für deine Hilfe...

Bei FTagsObj.OnValueChanged findet es OnValuechanged nicht obwohl diese property in DXSTAGLib_TLB drin ist und ich die DXSTAGSLib_TLB unter uses eingetragen habe.
Muss FTagsObj als TObject deklariert sein?

shmia 7. Mär 2006 13:49

Re: Zurück geliefertes Objekt "halten"
 
Zitat:

Zitat von LaNtHaN
Muss FTagsObj als TObject deklariert sein?

Nicht als TObject, sondern als TTags. TTags ist von TObjekt, genauer gesagt von TOleServer abgeleitet.
Delphi-Quellcode:
// deklaration
   FTagsObj : TTags;
Lies mal in der Online-Hilfe zu "TOleServer" nach, dann wird's klarer.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:09 Uhr.
Seite 1 von 2  1 2      

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