我有一个自定义COM服务器实现.服务器正在使用TComObjectFactory来创建用于客户端连接的COM对象.
我写得像这样:
function TPsOPCProviderClientFactory.CreateComObject(const Controller:
IUnknown): TComObject;
begin
FStartupCompleteEvent.WaitFor(INFINITE);
if Provider.State = OPC_STATUS_SUSPENDED then // Server already shutdown
raise EAbort.Create('Server shut down.');
Result := inherited CreateComObject(Controller);
(Result as TPsOPCProviderClient).Provider := Provider;
end;
Run Code Online (Sandbox Code Playgroud)
FStartupCompleteEvent用于确保应用程序在第一个连接通过之前就绪,并且Provider.State用于在服务器关闭时禁用客户端连接.
现在看来这不是取消对象创建的正确方法:如果引发异常,它将在屏幕上弹出一个带有"DAX Error"的消息对话框,客户端可能会崩溃.
使对象创建失败的正确方法是什么 - 或者是否必须始终成功?
该代码用于自Delphi 5以来可用于所有Delphi/C++ Builder版本的组件框架.
您不应该让任何异常从DllGetClassObjectCOM入口点逃脱.相反,您应该捕获此异常并返回适当的HResult值(可能E_UNEXPECTED).
它可能看起来像这样:
function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult;
begin
try
Result := ComServ.DllGetClassObject(CLSID, IID, Obj);
except
Pointer(Obj) := nil;
Result := E_UNEXPECTED;
end;
end;
Run Code Online (Sandbox Code Playgroud)
编辑:或者,修改您的CreateComObject方法以返回nil而不是引发异常会更简单.在这种情况下,默认DllGetClassObject实现ComServ将返回CLASS_E_CLASSNOTAVAILABLE.