Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TThread and COM - "CoInitialize has not been called", although CoInitialize is called in the constructor

I'm trying to use COM interface within a thread. From what I have read I have to call CoInitialize/CoUninitialize in each thread.

While this is working fine:

procedure TThreadedJob.Execute;
begin
   CoInitialize(nil);

   // some COM stuff

   CoUninitialize;
end;

when I move the calls to constructor and destructor:

TThreadedJob = class(TThread)
...
  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
...

constructor TThreadedJob.Create;
begin
  inherited Create(True);
  CoInitialize(nil);
end;

destructor TThreadedJob.Destroy;
begin
  CoUninitialize;
  inherited;
end;

procedure TThreadedJob.Execute;
begin

   // some COM stuff

end;

I get EOleException: CoInitialize has not been called exception and I have no clue why.

like image 247
forsajt Avatar asked Aug 15 '16 20:08

forsajt


1 Answers

CoInitialize initializes COM for the executing thread. The constuctor of a TThread instance executes in the thread that creates the TThread instance. The code in the Execute method executes in the new thread.

This means that if you need your TThreadedJob thread to have COM initialized, then you must call CoInitialize in the Execute method. Or a method called from Execute. The following is correct:

procedure TThreadedJob.Execute;
begin
  CoInitialize(nil);
  try    
    // some COM stuff
  finally  
    CoUninitialize;
  end;
end;
like image 72
David Heffernan Avatar answered Oct 22 '22 15:10

David Heffernan