3

カスタム 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 エラー」ポップアップを含むメッセージ ダイアログが表示され、クライアントがクラッシュする可能性があります。

オブジェクトの作成を失敗させる正しい方法は何ですか?または常に成功することは必須ですか?

コードは、Delphi 5 以降のすべての Delphi/C++Builder バージョンで利用可能なコンポーネント フレームワークで使用されます。

4

1 に答える 1

5

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;

CreateComObject編集: または、例外を発生させる代わりに、nil を返すようにメソッドを変更する方が簡単です。その場合、デフォルトのDllGetClassObject実装ComServが返さCLASS_E_CLASSNOTAVAILABLEれます。

于 2012-12-12T12:40:26.947 に答える