Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   ComObj und Thread (https://www.delphipraxis.net/180467-comobj-und-thread.html)

EWeiss 22. Mai 2014 08:16

ComObj und Thread
 
ComObj in Verbindung mit Thread nicht Thread sicher?

CoInitialize und CoUniitialize verwende ich nicht.
Das Obj wird in einer anderen Classe initialisiert welche aber keine Thread Anbindung hat.
Ist also nur eine Hilfklasse.

Delphi-Quellcode:
    if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
      IUnknown, ObjInstance) = S_OK then
Mit Thread laufen einige Plugins nicht ohne also mit Timer funktioniert es.

Habt ihr auch ähnliche Erfahrungen gemacht?

gruss

Sir Rufo 22. Mai 2014 08:24

AW: ComObj und Thread
 
Das ist aber bekannt und aus dem Grund ruft man in einem Thread, der solche ComObj benutzt immer
Delphi-Quellcode:
CoInitialize
und
Delphi-Quellcode:
CoUninitialize
auf.

Prominentes Beispiel dafür sind die ADO-Komponenten.

Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  inherited;
  CoInitialize( nil );
  try
    DoExecute;
  finally
    CoUninitialize;
  end;
end;

procedure TMyThread.DoExecute;
begin
  while not Terminated do
  begin
    ...
  end;
end;

EWeiss 22. Mai 2014 08:49

AW: ComObj und Thread
 
Zitat:

Zitat von Sir Rufo (Beitrag 1259727)
Das ist aber bekannt und aus dem Grund ruft man in einem Thread, der solche ComObj benutzt immer
Delphi-Quellcode:
CoInitialize
und
Delphi-Quellcode:
CoUninitialize
auf.

Prominentes Beispiel dafür sind die ADO-Komponenten.

Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  inherited;
  CoInitialize( nil );
  try
    DoExecute;
  finally
    CoUninitialize;
  end;
end;

procedure TMyThread.DoExecute;
begin
  while not Terminated do
  begin
    ...
  end;
end;


Also doch..
Die Frage ist nur wo sollte man die Initialisierung aufrufen bzw Uninitialisieren.
Jedesmal wenn ich ein neues ComObj erstelle und wieder freigebe ?
Ein TMyThread.Execute gibt es ja bei mir nicht da ich den Thread mit Win32 mitteln erstelle siehe

Delphi-Quellcode:
WMPThreadHandle := BeginThread(nil, 0, @BassWMPVisThread, pointer(PresetIndex),
  0, WMP_RenderThreadId);
Mein RenderThread basiert auf TThread dieser hat aber nichts mit dem Hauptthread gemein.
Es sollte aber kein Problem diesbezüglich entstehen denn aus diesen Thread sende ich alle Messagen über Events.
Sample..
Delphi-Quellcode:
PostThreadMessage(DriveThreadId, FDataReadyMsg, DataReady, 0);

gruss

jensw_2000 22. Mai 2014 08:54

AW: ComObj und Thread
 
Zitat:

Zitat von EWeiss (Beitrag 1259734)
Die Frage ist nur wo sollte man die Initialisierung aufrufen bzw Uninitialisieren.
Jedesmal wenn ich ein neues ComObj erstelle und wieder freigebe ?

Nein.
CoInitialize - jedesmal wenn Du eine neue Thread Instanz erstellst
CoUnInitialize - kurz bevor der Thread terminiert


PS:
Com muss in multithread Umgebungen auch entsprechend initialisiert werden ...
Delphi-Quellcode:
CoInitializeEx(nil, coinit_multithreaded)

DeddyH 22. Mai 2014 08:55

AW: ComObj und Thread
 
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Zitat:

You need to initialize the COM library on a thread before you call any of the library functions except CoGetMalloc, to get a pointer to the standard allocator, and the memory allocation functions.
Zitat:

To close the COM library gracefully, each successful call to CoInitialize or CoInitializeEx, including those that return S_FALSE, must be balanced by a corresponding call to CoUninitialize.
Das bedeutet in meiner Lesart: vor der ersten Benutzung einer der enthaltenen Funktionen CoInitialize aufrufen und nach der Abarbeitung der letzten dann CoUninitialize.

EWeiss 22. Mai 2014 08:57

AW: ComObj und Thread
 
Zitat:

Zitat von jensw_2000 (Beitrag 1259735)
Zitat:

Zitat von EWeiss (Beitrag 1259734)
Die Frage ist nur wo sollte man die Initialisierung aufrufen bzw Uninitialisieren.
Jedesmal wenn ich ein neues ComObj erstelle und wieder freigebe ?

Nein.
CoInitialize - jedesmal wenn Du eine neue Thread Instanz erstellst
CoUnInitialize - kurz bevor der Thread terminiert

Vorher also vor BeginThread?
Oder direkt im Anschluss.

CoUnInitialize dann bevor ich ExitThread(0); abfeuere.

gruss

jensw_2000 22. Mai 2014 09:02

AW: ComObj und Thread
 
Bevor der Thread gestartet wird (eine Chance hat auf die Com zuzugreifen).

Sir Rufo 22. Mai 2014 09:16

AW: ComObj und Thread
 
So wie ich das verstanden habe muss das innerhalb des Thread-Kontext aufgerufen werden wo das ComObj dann auch benutzt wird.

EWeiss 22. Mai 2014 09:19

AW: ComObj und Thread
 
Zitat:

Zitat von Sir Rufo (Beitrag 1259744)
So wie ich das verstanden habe muss das innerhalb des Thread-Kontext aufgerufen werden wo das ComObj dann auch benutzt wird.

Ich hab es mal versucht aber es macht keinen Unterschied ob mit oder ohne.
Hmm wider mal so ein Problem. ;)

Sollte nicht so einfach sein denn der Thread ist in einer DLL und wird von außen gesteuert.

Danke für eure Hilfe muss mich mal intensiver damit beschäftigen.

Der Thread wird ja in einer Funktion erstellt nicht zum aktuellen Thread-Kontext zählt.
Ist eine einfache Classe in der die API Messagen/Funktionen von der Anwendung zur DLL geschickt werden
Vielleicht muss ich die Execute Funktion dann in der Classe einlagern zu der mein Thread gehört.

Ist immer ein Kampf wenn das eine zum anderen nicht passt.

gruss

EWeiss 22. Mai 2014 10:38

AW: ComObj und Thread
 
Hab gerade was gefunden in wie weit ist das Aussagekräftig?

Zitat:

On a different note, ComObj calls CoInitialize/Ex only for EXEs, not for DLLs. A DLL's lifetime and threading requirements is a subset of its host application. Therefore, it is the responsibility of the host application to initialize the COM runtime before calling into a DLL application. Explicitly calling CoInitialize/Ex in a DLL can result in unpredictable behavior and nasty runtime failures.
EDIT:
Ok das wars ;)
Innerhalb der DLL hat das keinerlei Auswirkung.
Wenn ich hingegen die Initialisierung in der EXE ausführe bevor ich das Plugin starte funktioniert es.

gruss


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