如何从TComObjectFactory.CreateComObject返回错误(const Controller:IUnknown):TComObject

时间:2012-12-12 12:03:35

标签: delphi com

我有一个自定义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;

FStartupCompleteEvent用于确保应用程序在第一个连接通过之前就绪,并且Provider.State用于在服务器关闭时禁用客户端连接。

现在看来这不是取消对象创建的正确方法:如果引发异常,它将在屏幕上弹出“DAX Error”弹出消息对话框,客户端可能会崩溃。

使对象创建失败的正确方法是什么 - 或者是否必须始终成功?

该代码用于自Delphi 5以来可用于所有Delphi / C ++ Builder版本的组件框架。

1 个答案:

答案 0 :(得分:5)

您不应该让任何异常从DllGetClassObject COM入口点逃脱。 相反,您应该捕获此异常并返回适当的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;

编辑:或者,修改CreateComObject方法返回nil而不是引发异常会更简单。在这种情况下,DllGetClassObject中的默认ComServ实施将返回CLASS_E_CLASSNOTAVAILABLE