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

1

9

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.

Rosenwald answered 15/8, 2016 at 20:18 Comment(0)
A
20

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;
Anon answered 15/8, 2016 at 20:23 Comment(1)
Thank you for lightning fast answer.Rosenwald

© 2022 - 2024 — McMap. All rights reserved.