2015-04-23 6 views
5

Il mio server COM implementato in Visual C++ utilizza una tonnellata di altro codice C++. L'altro codice C++ a volte esegue il wrapping del codice in __try - __except e converte le eccezioni strutturate in eccezioni C++ personalizzate. Questa parte non posso cambiare.Come esporre tramite COM un'eccezione rilevata con la gestione delle eccezioni strutturate?

Nessun metodo del mio server COM deve consentire la propagazione di tali eccezioni attraverso il limite COM in modo che debba intercettarle e convertirle in HRESULT s. Quelle eccezioni C++ personalizzate contengono il codice di errore originale che è stato ottenuto durante la traduzione - è qualcosa come EXCEPTION_ACCESS_VIOLATION. La domanda è come modifico un valore appropriato HRESULT in modo che il client abbia quante più informazioni possibili su quanto accaduto (e forse decide di riavviare il server (e se stesso in caso di inproc) dopo aver visto una violazione di accesso).

Supponiamo che sia EXCEPTION_ACCESS_VIOLATION che è definito in WinBase.h

#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION 

e quest'ultimo è definita WinNT.h

#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L) 

ho potuto utilizzare HRESULT_FROM_WIN32() per tradurre il codice in HRESULT supponendo che era un Errore Win32 in primo luogo.

Devo utilizzare HRESULT_FROM_WIN32() qui o devo utilizzare in altro modo per eseguire la traduzione?

+0

Forse l'utilizzo dell'infrastruttura '' IErrorInfo'' può tornare utile qui. '' _com_error'' contiene un puntatore. Dal lato del callee, penso di ricordare che c'era qualcosa come SetErrorInfo ... Ho usato ATL allora ... * cough * Era 10 anni fa? – BitTickler

+0

@ user2225104 Anche con 'IErrorInfo' sono responsabile della creazione di un valore' HRESULT'. – sharptooth

+0

0xC0000005 è già un codice HRESULT valido che indica un errore, nessun motivo per modificarlo. Non nascondere qualcosa di così brutto. –

risposta

4

Si suppone di dover restituire il codice HRESULT, in cui si sceglie il codice appropriato per indicare lo stato dell'operazione. Non deve essere un codice di errore, ma in genere si desidera mostrare qualcosa che soddisfi la macro FAILED(...), ad es. E_FAIL o DISP_E_EXCEPTION o HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION).

È altamente improbabile che i chiamanti si confrontino con uno specifico HRESULT relativo alle eccezioni, pertanto un codice di errore specifico ha senso piuttosto per la diagnostica. Inoltre, man mano che si completa la gestione dell'eccezione prima di uscire dal metodo COM, non è necessario restituire il codice specifico HRESULT perché non sono necessarie o necessarie ulteriori azioni.

Per fornire ulteriori informazioni, è possibile utilizzare ISupportErrorInfo, IErrorInfo and friends. I chiamanti possono recuperare automaticamente la descrizione del testo libero e molti ambienti popolari, quindi ad esempio il chiamante .NET avrà queste informazioni aggiuntive sul messaggio di eccezione anziché sul messaggio standard generato dal codice HRESULT.

ATL offre AtlReportError per avvolgere SetErrorInfo API, che suggerisce anche sulla generazione HRESULT codice:

... Se hRes è zero, allora le prime quattro versioni di AtlReportError ritorno DISP_E_EXCEPTION. Le ultime due versioni restituiscono il risultato della macro MAKE_HRESULT(1, FACILITY_ITF, nID).

+0

Penso che l'OP non sia sicuro, indipendentemente dal fatto che il 'HRESULT 'passato attraverso l'interfaccia debba rappresentare la causa principale. Forse potresti sottolineare che in genere non è necessario trasportare le informazioni specifiche oltre i limiti dell'interfaccia. I tuoi primi due paragrafi lo affermano già, ma potrebbe essere utile dare una spiegazione esplicita. – IInspectable

+1

@IInspectable La causa principale può essere di grande interesse per il chiamante - se c'è stata un'eccezione strutturata il server potrebbe ottenere brindisi e il client riavviare meglio il server (e se stesso se fosse un server in-proc). – sharptooth

+0

@IInspectable: non vi è alcuna incertezza sul passaggio dell'eccezione oltre i limiti qui. È piuttosto su ciò che può/dovrebbe essere restituito standard usando le strategie COM. COM, tuttavia, obbliga solo a gestire le eccezioni ea restituire i codici HRESULT, lasciando quindi ai client/server la definizione di codice server specifico per indicare un errore fatale. –