c++ - todas - ¿Cómo expongo a través de COM una excepción atrapada con manejo de excepciones estructuradas?
try catch java (1)
Se supone que debes devolver el código HRESULT
, donde eliges el código apropiado para indicar el estado de la operación. No tiene que ser un código de falla, pero normalmente desea mostrar algo que satisfaga la macro FAILED(...)
, por ejemplo, DISP_E_EXCEPTION
o HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)
o HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)
.
Es muy poco probable que los llamantes se comparen con HRESULT
específico relacionado con la excepción, por lo que el código de falla específico tiene sentido más bien que el diagnóstico. Además, a medida que completa el manejo de la excepción antes de salir del método COM, no es necesario devolver el código HRESULT
específico porque no se requieren acciones adicionales o es necesario.
Para proporcionar información adicional, es posible utilizar ISupportErrorInfo
, IErrorInfo
y amigos . Las personas que llaman pueden recuperar automáticamente la descripción de texto libre y muchos entornos populares, por lo que, por ejemplo, la persona que llama .NET tendrá esta información adicional sobre el mensaje de excepción en lugar del mensaje estándar generado a partir del código HRESULT
.
ATL ofrece AtlReportError
para envolver la API SetErrorInfo
, que también sugiere generar código HRESULT
:
... Si
hRes
es cero, las primeras cuatro versiones deAtlReportError
devuelvenDISP_E_EXCEPTION
. Las dos últimas versiones devuelven el resultado de la macroMAKE_HRESULT( 1, FACILITY_ITF, nID )
.
Mi servidor COM implementado en Visual C ++ usa muchos otros códigos C ++. Ese otro código C ++ a veces ajusta el código en __try
- __except
y traduce las excepciones estructuradas en excepciones personalizadas de C ++. Esta parte no puedo cambiar.
Ningún método de mi servidor COM debería permitir que esas excepciones se propaguen a través del límite COM, por lo que debe capturarlas y traducirlas a HRESULT
s. Esas excepciones personalizadas de C ++ contienen el código de error original que se obtuvo durante la traducción, es algo así como EXCEPTION_ACCESS_VIOLATION
. La pregunta es cómo creo un valor HRESULT
apropiado para que el cliente tenga tanta información como sea posible sobre lo que sucedió (y tal vez decida reiniciar el servidor (y en sí mismo en caso de inproc) después de ver una violación de acceso).
Supongamos que fue EXCEPTION_ACCESS_VIOLATION
que se define en WinBase.h
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
y el último se define en WinNT.h
#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
Podría usar HRESULT_FROM_WIN32()
para traducir ese código en HRESULT
suponiendo que era un error de Win32 en primer lugar.
¿Uso HRESULT_FROM_WIN32()
aquí o utilizo otra forma de hacer la traducción?