구조화 예외 처리(SEH)의 with DirectX 정보
일반 예외
제로 마이너스, 방문 위반 등 하위 등급 예외(SE)는 할 수 없다.붕괴될 거야.try {
throw std::exception("hoge");
} catch (exception capture) {
std::cout << capture.what() << std::endl;
} catch (...) {
std::cout << "Unknown" << std::endl;
} finally {
...
}
구조적 예외
이렇게 하면 SE를 보충할 수 있다.
단, 함수 내에서try-catch와 병용할 수 없습니다.std::function
주 설치를 외부에 두면 몇 분 정도 걸릴 수 있습니다._EXCEPTION_POINTERS* info = nullptr;
__try {
auto hoge = 1 / ZERO; // 0徐算
nullObject->Invoke(); // アクセス違反
} __except(info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) {
auto code = info->ExceptionRecord->ExceptionCode;
std::cout << code << std::endl;
throw exception(std::to_string(code)); // これで外側のtry-catchに伝播できる(※)
} __finally {
...
}
SE를 예외로 자동 변환 옵션
이 옵션은 SE가 발생할 때 자동으로 C++ 예외로 변환되어 성능상의 벌칙을 바꿀 수 있습니다.하지만 SE의 내용은 빼낼 수 없다.
또한 Debug 작성 시 옵션이 유효하지 않아도 변환됩니다.(쓸데없는 일에 참견해라...)try { ... }
catch(std::exception e) { ... }
catch(...){
// ここに来る、「何が起こったか」は分からない
}
_set_se_translator
EHa를 유효성화한 뒤 등록하면 선호하는 예외 형태로 전환할 수 있다._set_se_translator([](unsigned int code, _EXCEPTION_POINTERS* ep) -> void {
throw exception(std::to_string(code));
});
try { ... }
catch(std::exception e) {
// ここに来る、_set_se_translatorで、例外オブジェクト内に入れた内容が参照できる
} catch(...){ ... }
DirectX용 SEH
DirectX는 COM으로 원래 오류는 SE에서 보고되지 않고 HRESULT에서 보고된다.
다만, HRESULT 방법으로 돌아가지 않거나, COM Object의 Release에서 문제가 발생하면 SE를 보낼 수 있습니다.
SEH 블록/함수 내throw 불가
본론입니다.
COM의 모든 이야기일지도 모르지만 throw 자체가 SE여서 호출 원본으로 복구할 수 없는 함수를 제어합니다.
만약 C++ 예외로 사용할 수 없다면, 매개 변수와 되돌아오는 값으로만 SE를 전달할 수 있습니다.매개변수를 조작할 수 없습니다_set_se_translator
. 사용할 수 없습니다.(전역 변수를 사용하면 안 되는 것도 아닌데...)
타협안
상술한 제약에서 나는 코드의 열화는 최소한의 통제 아래 대응할 수 있는 방법이라고 생각한다.void HandleStructuredException(std::function<void()> *callback, unsigned int &code) {
__try { callback->operator()(); }
__except (EXCEPTION_EXECUTE_HANDLER) { code = GetExceptionCode(); }
}
unsigned int seCode = 0;
std::function<void()> callback = [&]() -> void {
// メイン処理
};
HandleStructuredException(&callback, seCode);
if(seCode != 0) throw std::exception(std::to_string(seCode).data());
GetExceptionCode
대신 GetExceptionInformation
를 사용하면 더 자세한 (주소 등)을 얻을 수 있지만 지침이기 때문에 딥 복제가 필요하다.
콜백은 바늘로 전달되지만 SEH를 실현하는 함수에서는 대상 각도에서 탈출할 때의 분석기를 사용할 수 없기 때문이다.
MSDN 컴파일러 오류 C2712
Widnow 메시지 루프 안팎의 예외 전파(추가)
소식 순환 중에 발생하는 예외는 순환 도로 밖으로 전파될 수 없다.더 정확히 말하면 DispatchMessage → ... → WNDCLASSEX.lpfnWndProc
라고 불리지만 예외적으로 여기서 뛰어갈 수는 없다.
정보 순환 속에서 여러 윈도우가 현재와 동거하고 있다는 점을 고려하면 어쩔 수 없는 것 같다.
윈도 대상을 MSG 구조의 WHND에 연결하면 실례 필드를 사용하여 예외 인수인계를 하는 부분_set_se_translator
보다 조금 낫다.int main(int argc, char* argc[]) {
...
auto windowHandle = CreateWindow( ... );
SetWindowLongPtr(windowHandle , GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
...
try {
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
auto window = reinterpret_cast<Window *>(GetWindowLongPtr(message.hwnd, GWLP_USERDATA));
if(window != nullptr && window->Error() != nullptr) {
throw *window->Error();
}
...
}
} catch { ... }
...
}
MSDN WindowProc callback function
총결산
원래는 어디까지 처리해야 할지 문제가 있었다.
SEH를 진행해야 하는 시점에 버그가... 핸들을 통해 복구될 수도 없고.
그렇긴 하지만 할 수 있는 일이 없어도 무너지기 전에 미안하다고 말하고 싶어요.
세상에 나오는 C++에 그려진 Windows 응용 프로그램은 이 근처에서 어떻게 만들어졌을까.
참고 자료
try {
throw std::exception("hoge");
} catch (exception capture) {
std::cout << capture.what() << std::endl;
} catch (...) {
std::cout << "Unknown" << std::endl;
} finally {
...
}
이렇게 하면 SE를 보충할 수 있다.
단, 함수 내에서try-catch와 병용할 수 없습니다.
std::function
주 설치를 외부에 두면 몇 분 정도 걸릴 수 있습니다._EXCEPTION_POINTERS* info = nullptr;
__try {
auto hoge = 1 / ZERO; // 0徐算
nullObject->Invoke(); // アクセス違反
} __except(info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) {
auto code = info->ExceptionRecord->ExceptionCode;
std::cout << code << std::endl;
throw exception(std::to_string(code)); // これで外側のtry-catchに伝播できる(※)
} __finally {
...
}
SE를 예외로 자동 변환 옵션
이 옵션은 SE가 발생할 때 자동으로 C++ 예외로 변환되어 성능상의 벌칙을 바꿀 수 있습니다.하지만 SE의 내용은 빼낼 수 없다.
또한 Debug 작성 시 옵션이 유효하지 않아도 변환됩니다.(쓸데없는 일에 참견해라...)try { ... }
catch(std::exception e) { ... }
catch(...){
// ここに来る、「何が起こったか」は分からない
}
_set_se_translator
EHa를 유효성화한 뒤 등록하면 선호하는 예외 형태로 전환할 수 있다._set_se_translator([](unsigned int code, _EXCEPTION_POINTERS* ep) -> void {
throw exception(std::to_string(code));
});
try { ... }
catch(std::exception e) {
// ここに来る、_set_se_translatorで、例外オブジェクト内に入れた内容が参照できる
} catch(...){ ... }
DirectX용 SEH
DirectX는 COM으로 원래 오류는 SE에서 보고되지 않고 HRESULT에서 보고된다.
다만, HRESULT 방법으로 돌아가지 않거나, COM Object의 Release에서 문제가 발생하면 SE를 보낼 수 있습니다.
SEH 블록/함수 내throw 불가
본론입니다.
COM의 모든 이야기일지도 모르지만 throw 자체가 SE여서 호출 원본으로 복구할 수 없는 함수를 제어합니다.
만약 C++ 예외로 사용할 수 없다면, 매개 변수와 되돌아오는 값으로만 SE를 전달할 수 있습니다.매개변수를 조작할 수 없습니다_set_se_translator
. 사용할 수 없습니다.(전역 변수를 사용하면 안 되는 것도 아닌데...)
타협안
상술한 제약에서 나는 코드의 열화는 최소한의 통제 아래 대응할 수 있는 방법이라고 생각한다.void HandleStructuredException(std::function<void()> *callback, unsigned int &code) {
__try { callback->operator()(); }
__except (EXCEPTION_EXECUTE_HANDLER) { code = GetExceptionCode(); }
}
unsigned int seCode = 0;
std::function<void()> callback = [&]() -> void {
// メイン処理
};
HandleStructuredException(&callback, seCode);
if(seCode != 0) throw std::exception(std::to_string(seCode).data());
GetExceptionCode
대신 GetExceptionInformation
를 사용하면 더 자세한 (주소 등)을 얻을 수 있지만 지침이기 때문에 딥 복제가 필요하다.
콜백은 바늘로 전달되지만 SEH를 실현하는 함수에서는 대상 각도에서 탈출할 때의 분석기를 사용할 수 없기 때문이다.
MSDN 컴파일러 오류 C2712
Widnow 메시지 루프 안팎의 예외 전파(추가)
소식 순환 중에 발생하는 예외는 순환 도로 밖으로 전파될 수 없다.더 정확히 말하면 DispatchMessage → ... → WNDCLASSEX.lpfnWndProc
라고 불리지만 예외적으로 여기서 뛰어갈 수는 없다.
정보 순환 속에서 여러 윈도우가 현재와 동거하고 있다는 점을 고려하면 어쩔 수 없는 것 같다.
윈도 대상을 MSG 구조의 WHND에 연결하면 실례 필드를 사용하여 예외 인수인계를 하는 부분_set_se_translator
보다 조금 낫다.int main(int argc, char* argc[]) {
...
auto windowHandle = CreateWindow( ... );
SetWindowLongPtr(windowHandle , GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
...
try {
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
auto window = reinterpret_cast<Window *>(GetWindowLongPtr(message.hwnd, GWLP_USERDATA));
if(window != nullptr && window->Error() != nullptr) {
throw *window->Error();
}
...
}
} catch { ... }
...
}
MSDN WindowProc callback function
총결산
원래는 어디까지 처리해야 할지 문제가 있었다.
SEH를 진행해야 하는 시점에 버그가... 핸들을 통해 복구될 수도 없고.
그렇긴 하지만 할 수 있는 일이 없어도 무너지기 전에 미안하다고 말하고 싶어요.
세상에 나오는 C++에 그려진 Windows 응용 프로그램은 이 근처에서 어떻게 만들어졌을까.
참고 자료
try { ... }
catch(std::exception e) { ... }
catch(...){
// ここに来る、「何が起こったか」は分からない
}
EHa를 유효성화한 뒤 등록하면 선호하는 예외 형태로 전환할 수 있다.
_set_se_translator([](unsigned int code, _EXCEPTION_POINTERS* ep) -> void {
throw exception(std::to_string(code));
});
try { ... }
catch(std::exception e) {
// ここに来る、_set_se_translatorで、例外オブジェクト内に入れた内容が参照できる
} catch(...){ ... }
DirectX용 SEH
DirectX는 COM으로 원래 오류는 SE에서 보고되지 않고 HRESULT에서 보고된다.
다만, HRESULT 방법으로 돌아가지 않거나, COM Object의 Release에서 문제가 발생하면 SE를 보낼 수 있습니다.
SEH 블록/함수 내throw 불가
본론입니다.
COM의 모든 이야기일지도 모르지만 throw 자체가 SE여서 호출 원본으로 복구할 수 없는 함수를 제어합니다.
만약 C++ 예외로 사용할 수 없다면, 매개 변수와 되돌아오는 값으로만 SE를 전달할 수 있습니다.매개변수를 조작할 수 없습니다_set_se_translator
. 사용할 수 없습니다.(전역 변수를 사용하면 안 되는 것도 아닌데...)
타협안
상술한 제약에서 나는 코드의 열화는 최소한의 통제 아래 대응할 수 있는 방법이라고 생각한다.void HandleStructuredException(std::function<void()> *callback, unsigned int &code) {
__try { callback->operator()(); }
__except (EXCEPTION_EXECUTE_HANDLER) { code = GetExceptionCode(); }
}
unsigned int seCode = 0;
std::function<void()> callback = [&]() -> void {
// メイン処理
};
HandleStructuredException(&callback, seCode);
if(seCode != 0) throw std::exception(std::to_string(seCode).data());
GetExceptionCode
대신 GetExceptionInformation
를 사용하면 더 자세한 (주소 등)을 얻을 수 있지만 지침이기 때문에 딥 복제가 필요하다.
콜백은 바늘로 전달되지만 SEH를 실현하는 함수에서는 대상 각도에서 탈출할 때의 분석기를 사용할 수 없기 때문이다.
MSDN 컴파일러 오류 C2712
Widnow 메시지 루프 안팎의 예외 전파(추가)
소식 순환 중에 발생하는 예외는 순환 도로 밖으로 전파될 수 없다.더 정확히 말하면 DispatchMessage → ... → WNDCLASSEX.lpfnWndProc
라고 불리지만 예외적으로 여기서 뛰어갈 수는 없다.
정보 순환 속에서 여러 윈도우가 현재와 동거하고 있다는 점을 고려하면 어쩔 수 없는 것 같다.
윈도 대상을 MSG 구조의 WHND에 연결하면 실례 필드를 사용하여 예외 인수인계를 하는 부분_set_se_translator
보다 조금 낫다.int main(int argc, char* argc[]) {
...
auto windowHandle = CreateWindow( ... );
SetWindowLongPtr(windowHandle , GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
...
try {
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
auto window = reinterpret_cast<Window *>(GetWindowLongPtr(message.hwnd, GWLP_USERDATA));
if(window != nullptr && window->Error() != nullptr) {
throw *window->Error();
}
...
}
} catch { ... }
...
}
MSDN WindowProc callback function
총결산
원래는 어디까지 처리해야 할지 문제가 있었다.
SEH를 진행해야 하는 시점에 버그가... 핸들을 통해 복구될 수도 없고.
그렇긴 하지만 할 수 있는 일이 없어도 무너지기 전에 미안하다고 말하고 싶어요.
세상에 나오는 C++에 그려진 Windows 응용 프로그램은 이 근처에서 어떻게 만들어졌을까.
참고 자료
본론입니다.
COM의 모든 이야기일지도 모르지만 throw 자체가 SE여서 호출 원본으로 복구할 수 없는 함수를 제어합니다.
만약 C++ 예외로 사용할 수 없다면, 매개 변수와 되돌아오는 값으로만 SE를 전달할 수 있습니다.매개변수를 조작할 수 없습니다
_set_se_translator
. 사용할 수 없습니다.(전역 변수를 사용하면 안 되는 것도 아닌데...)타협안
상술한 제약에서 나는 코드의 열화는 최소한의 통제 아래 대응할 수 있는 방법이라고 생각한다.void HandleStructuredException(std::function<void()> *callback, unsigned int &code) {
__try { callback->operator()(); }
__except (EXCEPTION_EXECUTE_HANDLER) { code = GetExceptionCode(); }
}
unsigned int seCode = 0;
std::function<void()> callback = [&]() -> void {
// メイン処理
};
HandleStructuredException(&callback, seCode);
if(seCode != 0) throw std::exception(std::to_string(seCode).data());
GetExceptionCode
대신 GetExceptionInformation
를 사용하면 더 자세한 (주소 등)을 얻을 수 있지만 지침이기 때문에 딥 복제가 필요하다.
콜백은 바늘로 전달되지만 SEH를 실현하는 함수에서는 대상 각도에서 탈출할 때의 분석기를 사용할 수 없기 때문이다.
MSDN 컴파일러 오류 C2712
Widnow 메시지 루프 안팎의 예외 전파(추가)
소식 순환 중에 발생하는 예외는 순환 도로 밖으로 전파될 수 없다.더 정확히 말하면 DispatchMessage → ... → WNDCLASSEX.lpfnWndProc
라고 불리지만 예외적으로 여기서 뛰어갈 수는 없다.
정보 순환 속에서 여러 윈도우가 현재와 동거하고 있다는 점을 고려하면 어쩔 수 없는 것 같다.
윈도 대상을 MSG 구조의 WHND에 연결하면 실례 필드를 사용하여 예외 인수인계를 하는 부분_set_se_translator
보다 조금 낫다.int main(int argc, char* argc[]) {
...
auto windowHandle = CreateWindow( ... );
SetWindowLongPtr(windowHandle , GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
...
try {
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
auto window = reinterpret_cast<Window *>(GetWindowLongPtr(message.hwnd, GWLP_USERDATA));
if(window != nullptr && window->Error() != nullptr) {
throw *window->Error();
}
...
}
} catch { ... }
...
}
MSDN WindowProc callback function
총결산
원래는 어디까지 처리해야 할지 문제가 있었다.
SEH를 진행해야 하는 시점에 버그가... 핸들을 통해 복구될 수도 없고.
그렇긴 하지만 할 수 있는 일이 없어도 무너지기 전에 미안하다고 말하고 싶어요.
세상에 나오는 C++에 그려진 Windows 응용 프로그램은 이 근처에서 어떻게 만들어졌을까.
참고 자료
void HandleStructuredException(std::function<void()> *callback, unsigned int &code) {
__try { callback->operator()(); }
__except (EXCEPTION_EXECUTE_HANDLER) { code = GetExceptionCode(); }
}
unsigned int seCode = 0;
std::function<void()> callback = [&]() -> void {
// メイン処理
};
HandleStructuredException(&callback, seCode);
if(seCode != 0) throw std::exception(std::to_string(seCode).data());
소식 순환 중에 발생하는 예외는 순환 도로 밖으로 전파될 수 없다.더 정확히 말하면
DispatchMessage → ... → WNDCLASSEX.lpfnWndProc
라고 불리지만 예외적으로 여기서 뛰어갈 수는 없다.정보 순환 속에서 여러 윈도우가 현재와 동거하고 있다는 점을 고려하면 어쩔 수 없는 것 같다.
윈도 대상을 MSG 구조의 WHND에 연결하면 실례 필드를 사용하여 예외 인수인계를 하는 부분
_set_se_translator
보다 조금 낫다.int main(int argc, char* argc[]) {
...
auto windowHandle = CreateWindow( ... );
SetWindowLongPtr(windowHandle , GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
...
try {
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
auto window = reinterpret_cast<Window *>(GetWindowLongPtr(message.hwnd, GWLP_USERDATA));
if(window != nullptr && window->Error() != nullptr) {
throw *window->Error();
}
...
}
} catch { ... }
...
}
MSDN WindowProc callback function 총결산
원래는 어디까지 처리해야 할지 문제가 있었다.
SEH를 진행해야 하는 시점에 버그가... 핸들을 통해 복구될 수도 없고.
그렇긴 하지만 할 수 있는 일이 없어도 무너지기 전에 미안하다고 말하고 싶어요.
세상에 나오는 C++에 그려진 Windows 응용 프로그램은 이 근처에서 어떻게 만들어졌을까.
참고 자료
Reference
이 문제에 관하여(구조화 예외 처리(SEH)의 with DirectX 정보), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/up-hash/items/f8a2be028f8c271ab229텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)