以下代码是delphi实现Apartment模型的代码,它真正实现线程,
procedure TApartmentThread.Execute;
var
msg: TMsg;
Unk: IUnknown;
begin
try
CoInitialize(nil);
try
FCreateResult := FFactory.CreateInstanceLic(FUnkOuter, nil, FIID, '', Unk);
FUnkOuter := nil;
FFactory := nil;
if FCreateResult = S_OK then
CoMarshalInterThreadInterfaceInStream(FIID, Unk, IStream(FStream));
ReleaseSemaphore(FSemaphore, 1, nil);
if FCreateResult = S_OK then
while GetMessage(msg, 0, 0, 0)do
begin
DispatchMessage(msg);
Unk._AddRef;
if Unk._Release = 1 then
break;
end;
finally
Unk := nil;
CoUninitialize;
end;
except
{ No exceptions should go unhandled }
end;
end;
以下为Apartment模型的对象创建函数,
function TComponentFactory.CreateInstance(const UnkOuter: IUnknown;
const IID: TGUID;
out Obj): HResult;
stdcall;
begin
if not IsLibrary and (ThreadingModel = tmApartment) then
begin
LockServer(True);
try
with TApartmentThread.Create(Self, UnkOuter, IID)do
begin
if WaitForSingleObject(Semaphore, INFINITE) = WAIT_OBJECT_0 then
begin
Result := CreateResult;
if Result <> S_OK then
Exit;
Result := CoGetInterfaceAndReleaseStream(IStream(ObjStream), IID, Obj);
end else
Result := E_FAIL
end;
finally
LockServer(False);
end;
end else
Result := inherited CreateInstance(UnkOuter, IID, Obj);
end;
它通过建立一个单独的先程来对外提供服务,知道对象被释放,线程才结束运行,
GetMessage 是 不接受其他线程的消息
注意接口在线程间Marshal的代码,CoMarshalInterThreadInterfaceInStream和
CoGetInterfaceAndReleaseStream 函数,前一个函数Marshall一个接口,后一个取得
已经Marshall的接口。