2017-12-06 79 views
1

이 자동으로 오류 설명을 검색, how to throw 보통의 Win32 오류를 올바르게이며, 놀랍게 잘 작동 :FAILED (HRESULT)에서 std :: system_error 예외를 throw하는 방법은 무엇입니까?

if (!SomeWinFunc()) { 
    throw std::system_error(GetLastError(), 
    std::system_category(), 
    "SomeWinFunc crashed badly"); 
} 
그러나

, 나는이 같은 idiomatically을 체크 COM 오류에 대처하는 방법에 대한 불확실 해요 :

HRESULT hr = comObj->SomeFunc(); 
if (FAILED(hr)) { 
    throw std::system_error(hr, // <-- is it correct here? 
    std::system_category(), 
    "SomeFunc crashed right now"); 
} 

HRESULTsystem_error에 통과 정확, 또는 COM 기능에서 예외를 던질 수있는 또 다른 방법은 무엇입니까?

+0

어디서 났습니까? –

+0

@MichaelGunter, 100 % 올바른 솔루션 (코드로 시작할 수도 있음)을 아직 구현하지 못했지만, 시스템 요구 사항을 처리하기 위해 필요한 COM 코드를 사용하기 때문에 몇 가지 테스트를 수행했습니다. 나는 시간을 알 자마자 이것에 대해 더 깊은 곳으로 갈 계획이다. – Rodrigo

답변

3

일반적으로 Microsoft 표준 _com_error 예외 유형을 사용하여이 문제를 처리합니다. 예외 유형은 다음 중 하나로 쉽게 제기 할 수 있습니다.

_com_util::CheckError(hr); // throws when FAILED(hr) 
_com_issue_error(hr); // throws always 

는 Win32 오류 때문에 같은 HRESULT로 변환 할 수 있습니다 :

hr = HRESULT_FROM_WIN32(GetLastError()); 

그러나, 이것은 당신이 문제가 될 수있는 새로운 예외 유형, 처리해야한다는 것을 의미한다. 이것을 순수 STL 방식으로 수행하려면 새로운 error_category을 파생시켜 system_category 대신 사용해야한다고 생각합니다. <system_error> 헤더를보고 system_category 구현을 복사하고 HRESULT에 대해 필요에 따라 업데이트합니다.

은 이상적으로, HRESULT의 다른 facility codes 다른 error_category 구현에 의해 제공 될 것입니다 - 매우 효과적으로 예외 소스를 전달할 것이다 그렇게. 하지만 그건 까다 롭습니다. HRESULT을 일반적으로 다루는 하나의 com_category으로 벗어날 수 있습니다.

+0

'std :: system_category'를 문맥으로 사용할 때'** HRESULT'를 넘겨서는 안됩니다. 이 카테고리는'GetLastError'에 의해 반환 된 에러 코드와 함께 사용하기위한 것입니다. 예를 들어, COM 성공 코드'S_FALSE'를 넘겨 주면,'ERROR_INVALID_FUNCTION'으로 해석 될 것입니다. 커스텀'error_category' 구현 방법에 대한 정보는 [C++ 0x - part 4의 시스템 오류 지원] (http://blog.think-async.com/2010/04/system-error-support- in-c0x-part-4.html). – IInspectable

+1

@IInspectable'S_FALSE'는 에러 코드가 아니기 때문에 좋은 예가 아닙니다. 그래서 그것을 던질 이유가 없습니다. 'HRESULT' 오류가 항상 음수이기 때문에'HRESULT'가 나타낼 수있는 * 오류 * 값은'GetLastError'에 의해 반환 된 오류 코드와 겹치지 않습니다. 따라서 제 생각에는 'FAILED (hr) == true'값만 던질 때마다 'HRESULT'에 대한 특별한 범주가 필요하지 않습니다. – zett42

+0

@ zett42 : 코드 논리에 따라 다릅니다. 성공적인 COM 호출은 복구 할 수없고 throw해야하는 조건을 생성 할 수 있습니다. 그렇지 않은 경우에도 오류 메시지를 생성하려면 사용자 지정 오류 범주가 필요합니다. 'FormatMessage'는 시스템 정의 된'HRESULT' 값과 함께 사용될 수 있지만 고객이 정의한 코드를 다룰 때 상황이 다르게 보입니다. 오류 메시지, 즉 모듈 핸들로 변환하려면 추가 정보가 필요합니다. 오류 코드 옆에 추가 정보를 전달할 수 없으므로 해당 범주에 인코딩해야합니다. – IInspectable