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 CoInitialize Verständnisproblem (https://www.delphipraxis.net/169715-coinitialize-verstaendnisproblem.html)

ULIK 7. Aug 2012 11:33

CoInitialize Verständnisproblem
 
Ich habe gerade ein massives Verständnisproblem was Coinitialize / CoinitializeEx betrifft: wann verwendet man was.
Hier mal die Situation: ich habe eine VCL Anwendung, die auf die die Microsoft InkOverlay Klasse via COM zugreift. Zudem erzeugt die Anwendung gelegentlich eine Art Wächterthread, der nachschaut, ob dieses Objekt noch Daten aufnimmt. Dazu wird eine Referenz auf das Objekt mitgegeben, das selbst wiederum die Referenz auf das COM Objekt enthält. Von dieser Art Wächterthread können durchaus auch mehrere gleichzeitig aktiv laufen.
Soweit ich es nun bisher verstanden habe, muß sowohl die Anwendung selbst als auch jeder meiner Wächter-Threads Coinitialize(Ex) aufrufen. Aber: reicht hier nun das einfache Coinitialize oder sollte es CoinitializeEx(nil, COINIT_MULTITHREADED) sein?
Das InkOverlay selbst kann laut Doku sowohl in einem multithreaded als auch einem singelthreaded appartment laufen.

Irgendwie blick ich hier nun leider gar nicht mehr durch, was ich nun verwenden soll. Im Moment verwende ich Coinitialize aber da manche Kunden sehr seltsame Hänger melden wo das InkOverlay auf irgendetwas wartet ...


Danke,
Uli

Iwo Asnet 7. Aug 2012 11:46

AW: CoInitialize Verständnisproblem
 
Du vermischt "single/multithreaded appartment" mit "multithreaded application".

Ich mache es immer so:
Jeder thread ruft im Execute CoInitialze/CoUninitialize auf, instantiiert das Interface und arbeitet damit.
Delphi-Quellcode:
Procedure TMyThreadWithInterface.Execute;
Var
  MyInterface : IMyInterface;

Begin
  CoInitialize();
  MyInterface := CoMyInterface.Create();
  Try
    While not Terminated do WorkWith(MyInterface);
  Finally
    CoUninitialize();
  End
End;
Ich glaube, ein Interface bzw. den Zeiger kann man nicht zwischen Threads hin und her übergeben und deshalb instantiiere ich es im Execute.

ULIK 7. Aug 2012 12:07

AW: CoInitialize Verständnisproblem
 
Das Erstellen des Interfaces in jedem Thread geht bei mir glaub ich nicht, da nach meinem Verständnis dann ja immer eine neue Instanz des InkOverlays erstellt wird. Im benötige aber die gerade aktive Instanz, weil ich der wissen muß, ob sie noch Daten sammelt und erst wenn dies nicht der Fall ist, dann darf eine bestimmte Aktion ausgelöst werden.
Zumindest das Übergeben der Instanz an den Thread scheint keine Probleme zu machen (was vieleicht aber auch daran liegt, daß ich hier nicht direkt mit dem Interface sondern mit einer entsprechenden abgeleiteten TOleServer-Instanz arbeite, die das Interface verwaltet).
Auf alle Fälle werd ich mal das Coinitialize auch in die Execute-Methode des Threads selbst auch mitaufnehmen.

Vielen Dank,
Uli

Bernhard Geyer 7. Aug 2012 12:57

AW: CoInitialize Verständnisproblem
 
Wenn du COM-Interfaces auch in anderen Threads verwenden willst musst du diese Marshallen damit sie auch im anderen Thread gültig sind.
Weiß aktuell aber nicht mehr welche Win-API-Funktion dafür zuständig ist.

ULIK 7. Aug 2012 13:12

AW: CoInitialize Verständnisproblem
 
Da hab ich was gefunden: http://www.delphigroups.info/2/6d/261929.html.
Was mich jetzt dann aber wundert ist, wieso das dann bisher geht. Aus irgendeinem Grund hat der Thread nun bisher nie Probleme gehabt, auf das COM Object mittels der Referenz zuzugreifen. War das Zufall?

Aber vieleicht nochmal zurück zu meinen Ausgang (weil's mir immer noch nicht klar ist): was hat es denn mit dem CoinitializeEx(nil, COINIT_MULTITHREADED) auf sich? Oder reicht in meiner Situation das 'einfache' CoInitialize?


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