2015-04-23 9 views
5

Mój serwer COM zaimplementowany w Visual C++ wykorzystuje mnóstwo innych kodów C++. Ten inny kod C++ czasami zawija kod w __try - __except i tłumaczy uporządkowane wyjątki na niestandardowe wyjątki C++. Tej części nie mogę zmienić.Jak wyświetlić przez COM wyjątek złapany z obsługą strukturalnych wyjątków?

Żadna metoda mojego serwera COM nie powinna zezwalać na te wyjątki propagowane przez granicę COM, więc musi przechwycić i przetłumaczyć je na HRESULT s. Te niestandardowe wyjątki C++ zawierają oryginalny kod błędu, który został uzyskany podczas tłumaczenia - jest to coś w rodzaju EXCEPTION_ACCESS_VIOLATION. Pytanie brzmi, jak utworzyć odpowiednią wartość, tak aby klient miał jak najwięcej informacji o tym, co się stało (i może zdecydować o ponownym uruchomieniu serwera (i sam w przypadku inproc) po zobaczeniu naruszenia zasad dostępu).

Załóżmy, że było EXCEPTION_ACCESS_VIOLATION który jest zdefiniowany w WinBase.h

#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION 

i która jest określona w WinNT.h

#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L) 

można używać HRESULT_FROM_WIN32() do przetłumaczenia tego kodu w HRESULT przy założeniu, że jest to Win32 błąd w pierwszej kolejności.

Czy używam tutaj HRESULT_FROM_WIN32() lub czy używam innego sposobu tłumaczenia?

+0

Może przydać się tutaj infrastruktura '' IErrorInfo''. '' _com_error'' zawiera wskaźnik do niego. Po stronie odbiorcy, pamiętam, że było coś takiego jak SetErrorInfo ... Używałem wtedy ATL ... * kaszel * Czy to było 10 lat temu? – BitTickler

+0

@ user2225104 Nawet z 'IErrorInfo' jestem odpowiedzialny za tworzenie wartości' HRESULT'. – sharptooth

+0

0xC0000005 jest już prawidłowym kodem HRESULT, który wskazuje na błąd, brak powodu, aby go zmienić. Nie ukrywaj czegoś tak nieprzyjemnego. –

Odpowiedz

4

Należy zwrócić kod HRESULT, w którym należy wybrać odpowiedni kod, aby wskazać status operacji. Nie musi to być kod błędu, ale zazwyczaj chcesz pokazać coś, co spełnia makro, np. FAILED(...). E_FAIL lub DISP_E_EXCEPTION lub HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION).

Jest wysoce nieprawdopodobne, aby osoby dzwoniące porównały się z konkretnym związanym z wyjątkami HRESULT, więc określony kod błędu ma sens raczej w przypadku diagnostyki. Ponadto, po zakończeniu obsługi wyjątku przed wyjściem z metody COM, nie ma potrzeby zwracania konkretnego kodu HRESULT, ponieważ nie są wymagane żadne dodatkowe czynności.

Aby uzyskać dodatkowe informacje, można użyć ISupportErrorInfo, IErrorInfo and friends. Dzwoniący mogą automatycznie pobierać informacje o wolnym tekście i wielu popularnych środowiskach, więc na przykład .NET caller będzie miał te dodatkowe informacje na temat wiadomości wyjątku, a nie standardowy komunikat generowany z kodu HRESULT.

ATL oferuje AtlReportError zawinąć SetErrorInfo API, co sugeruje również na generowanie kodu HRESULT:

... Jeśli hRes jest zero, to pierwsze cztery wersje AtlReportError zamian DISP_E_EXCEPTION. Dwie ostatnie wersje zwracają wynik makra MAKE_HRESULT(1, FACILITY_ITF, nID).

+0

Uważam, że OP nie jest pewien, czy hasło "HRESULT" przekazywane przez interfejs powinno stanowić główną przyczynę. Może mógłbyś podkreślić, że generalnie nie ma potrzeby przenoszenia tych konkretnych informacji przez granice interfejsu. Twoje pierwsze dwa akapity już to stwierdzają, ale wyraźne sformułowanie może pomóc. – IInspectable

+1

@IInspectable Główna przyczyna może być bardzo interesująca dla osoby dzwoniącej - jeśli wystąpił strukturalny wyjątek, serwer mógł uzyskać toast, a klient lepiej zrestartował serwer (i sam, jeśli był serwerem w procesie). – sharptooth

+0

@IInspectable: Tutaj nie ma wątpliwości co do przekazywania wyjątków poza granice. Chodzi raczej o to, co może/powinno być zwrócony standard za pomocą strategii COM. COM, jednak, tylko zobowiązuje się do obsługi wyjątków i powrotu kodów HRESULT, pozostawiając klientów/serwerów do zdefiniowania kodu specyficznego dla serwera, aby wskazać błąd krytyczny. –

Powiązane problemy