2016-08-15 36 views
8

Próbuję użyć interfejsu COM w wątku. Z tego, co przeczytałem, muszę zadzwonić pod numer CoInitialize/CoUninitialize w każdym wątku.TThread i COM - "CoInitialize nie został wywołany", chociaż CoInitialize jest wywoływana w konstruktorze

Mimo to pracuje bez zarzutu:

procedure TThreadedJob.Execute; 
begin 
    CoInitialize(nil); 

    // some COM stuff 

    CoUninitialize; 
end; 

kiedy przenieść połączenia do konstruktora i destruktora:

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; 

uzyskać EOleException: CoInitialize nie została wywołana wyjątek, a ja nie mam wskazówka dlaczego.

Odpowiedz

18

CoInitialize inicjalizuje COM dla wykonywanego wątku. Instancja instancji TThread jest wykonywana w wątku, który tworzy instancję TThread. Kod w metodzie Execute jest wykonywany w nowym wątku.

Oznacza to, że jeśli chcesz, aby Twój wątek TThreadedJob został zainicjowany przez COM, musisz zadzwonić pod numer CoInitialize w metodzie Execute. Lub metoda nazwana od Execute. Następujące wartości są prawidłowe:

procedure TThreadedJob.Execute; 
begin 
    CoInitialize(nil); 
    try  
    // some COM stuff 
    finally 
    CoUninitialize; 
    end; 
end; 
+0

Dziękuję za błyskawiczną odpowiedź. – forsajt