방법: HRESULT 및 예외 매핑
업데이트: 2007년 11월
COM 메서드는 HRESULT를 반환하여 오류를 보고하고 .NET 메서드는 예외를 throw하여 보고합니다. 런타임은 이 둘 사이의 전환을 처리합니다. .NET Framework의 각 예외 클래스는 HRESULT에 매핑됩니다.
사용자 정의 예외 클래스는 적절한 HRESULT를 지정할 수 있습니다. 이 예외 클래스는 예외 개체에 HResult 필드를 설정하여 예외를 생성할 때 반환되는 HRESULT를 동적으로 변경할 수 있습니다. 예외에 대한 추가 정보는 관리되지 않는 프로세스에서 .NET 개체에 구현되는 IErrorInfo 인터페이스를 통해 클라이언트에 제공됩니다.
System.Exception을 확장하는 클래스를 만드는 경우 생성하는 동안 HRESULT 필드를 설정해야 합니다. 그렇지 않으면 기본 클래스에서 HRESULT 값을 할당합니다. 예외 생성자에서 값을 제공하여 새 예외 클래스를 기존의 HRESULT에 매핑할 수 있습니다.
런타임은 스레드에 IErrorInfo가 있는 경우 HRESULT를 무시하기도 합니다. 이러한 동작은 HRESULT와 IErrorInfo가 동일한 오류를 나타내지 않는 경우에 발생할 수 있습니다.
새 예외 클래스를 만들어 HRESULT에 매핑하려면
다음 코드를 사용하여 NoAccessException이라는 새 예외 클래스를 만든 다음 HRESULT E_ACCESSDENIED에 매핑합니다.
Class NoAccessException : public ApplicationException { NoAccessException () { HResult = E_ACCESSDENIED; } } CMyClass::MethodThatThrows { throw new NoAccessException(); }
관리 코드와 비관리 코드를 동시에 사용하는 프로그램(모든 프로그래밍 언어 사용 가능)을 발견할 수 있습니다. 예를 들어 다음 코드 예제에서 사용자 지정 마샬러는 Marshal.ThrowExceptionForHR(int HResult) 메서드를 사용하여 특정 HRESULT 값으로 예외를 throw합니다. 이 메서드는 HRESULT를 찾아서 적절한 예외 형식을 생성합니다. 예를 들어 다음 코드의 HRESULT는 ArgumentException을 생성합니다.
CMyClass::MethodThatThrows
{
Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}
다음 표에서는 각 HRESULT에서 .NET Framework의 해당 예외 클래스로의 전체 매핑을 제공합니다.
HRESULT |
.NET 예외 |
---|---|
MSEE_E_APPDOMAINUNLOADED |
AppDomainUnloadedException |
COR_E_APPLICATION |
ApplicationException |
COR_E_ARGUMENT 또는 E_INVALIDARG |
ArgumentException |
COR_E_ARGUMENTOUTOFRANGE |
ArgumentOutOfRangeException |
COR_E_ARITHMETIC 또는 ERROR_ARITHMETIC_OVERFLOW |
ArithmeticException |
COR_E_ARRAYTYPEMISMATCH |
ArrayTypeMismatchException |
COR_E_BADIMAGEFORMAT 또는 ERROR_BAD_FORMAT |
BadImageFormatException |
COR_E_COMEMULATE_ERROR |
COMEmulateException |
COR_E_CONTEXTMARSHAL |
ContextMarshalException |
COR_E_CORE |
CoreException |
NTE_FAIL |
CryptographicException |
COR_E_DIRECTORYNOTFOUND 또는 ERROR_PATH_NOT_FOUND |
DirectoryNotFoundException |
COR_E_DIVIDEBYZERO |
DivideByZeroException |
COR_E_DUPLICATEWAITOBJECT |
DuplicateWaitObjectException |
COR_E_ENDOFSTREAM |
EndOfStreamException |
COR_E_TYPELOAD |
EntryPointNotFoundException |
COR_E_EXCEPTION |
Exception |
COR_E_EXECUTIONENGINE |
ExecutionEngineException |
COR_E_FIELDACCESS |
FieldAccessException |
COR_E_FILENOTFOUND 또는 ERROR_FILE_NOT_FOUND |
FileNotFoundException |
COR_E_FORMAT |
FormatException |
COR_E_INDEXOUTOFRANGE |
IndexOutOfRangeException |
COR_E_INVALIDCAST 또는 E_NOINTERFACE |
InvalidCastException |
COR_E_INVALIDCOMOBJECT |
InvalidComObjectException |
COR_E_INVALIDFILTERCRITERIA |
InvalidFilterCriteriaException |
COR_E_INVALIDOLEVARIANTTYPE |
InvalidOleVariantTypeException |
COR_E_INVALIDOPERATION |
InvalidOperationException |
COR_E_IO |
IOException |
COR_E_MEMBERACCESS |
AccessException |
COR_E_METHODACCESS |
MethodAccessException |
COR_E_MISSINGFIELD |
MissingFieldException |
COR_E_MISSINGMANIFESTRESOURCE |
MissingManifestResourceException |
COR_E_MISSINGMEMBER |
MissingMemberException |
COR_E_MISSINGMETHOD |
MissingMethodException |
COR_E_MULTICASTNOTSUPPORTED |
MulticastNotSupportedException |
COR_E_NOTFINITENUMBER |
NotFiniteNumberException |
E_NOTIMPL |
NotImplementedException |
COR_E_NOTSUPPORTED |
NotSupportedException |
COR_E_NULLREFERENCE 또는 E_POINTER |
NullReferenceException |
COR_E_OUTOFMEMORY 또는 E_OUTOFMEMORY |
OutOfMemoryException |
COR_E_OVERFLOW |
OverflowException |
COR_E_PATHTOOLONG 또는 ERROR_FILENAME_EXCED_RANGE |
PathTooLongException |
COR_E_RANK |
RankException |
COR_E_REFLECTIONTYPELOAD |
ReflectionTypeLoadException |
COR_E_REMOTING |
RemotingException |
COR_E_SAFEARRAYTYPEMISMATCH |
SafeArrayTypeMismatchException |
COR_E_SECURITY |
SecurityException |
COR_E_SERIALIZATION |
SerializationException |
COR_E_STACKOVERFLOW 또는 ERROR_STACK_OVERFLOW |
StackOverflowException |
COR_E_SYNCHRONIZATIONLOCK |
SynchronizationLockException |
COR_E_SYSTEM |
SystemException |
COR_E_TARGET |
TargetException |
COR_E_TARGETINVOCATION |
TargetInvocationException |
COR_E_TARGETPARAMCOUNT |
TargetParameterCountException |
COR_E_THREADABORTED |
ThreadAbortException |
COR_E_THREADINTERRUPTED |
ThreadInterruptedException |
COR_E_THREADSTATE |
ThreadStateException |
COR_E_THREADSTOP |
ThreadStopException |
COR_E_TYPELOAD |
TypeLoadException |
COR_E_TYPEINITIALIZATION |
TypeInitializationException |
COR_E_VERIFICATION |
VerificationException |
COR_E_WEAKREFERENCE |
WeakReferenceException |
COR_E_VTABLECALLSNOTSUPPORTED |
VTableCallsNotSupportedException |
다른 모든 HRESULT |
COMException |
확장된 오류 정보를 검색하려면 관리되는 클라이언트가 생성된 예외 개체의 필드를 검토해야 합니다. 예외 개체에서 오류에 관한 유용한 정보를 제공하기 위해 COM 개체는 IErrorInfo 인터페이스를 구현해야 합니다. 런타임은 IErrorInfo에서 제공하는 정보를 사용하여 예외 개체를 초기화합니다.
COM 개체에서 IErrorInfo를 지원하지 않는 경우 런타임은 기본값을 사용하여 예외 개체를 초기화합니다. 다음 표에서는 예외 개체와 관련된 각 필드를 나열하고 COM 개체가 IErrorInfo를 지원하는 경우 기본 정보의 소스를 식별합니다.
런타임은 스레드에 IErrorInfo가 있는 경우 HRESULT를 무시하기도 합니다. 이러한 동작은 HRESULT와 IErrorInfo가 동일한 오류를 나타내지 않는 경우에 발생할 수 있습니다.
예외 필드 |
COM의 정보 소스 |
---|---|
ErrorCode |
호출에서 반환된 HRESULT |
HelpLink |
IErrorInfo->HelpContext가 0이 아닌 경우 IErrorInfo->GetHelpFile, "#", IErrorInfo->GetHelpContext를 연결하여 문자열을 구성합니다. 그렇지 않은 경우에는 IErrorInfo->GetHelpFile에서 문자열이 반환됩니다. |
InnerException |
항상 null 참조(Visual Basic에서는 Nothing) |
Message |
IErrorInfo->GetDescription에서 반환된 문자열 |
Source |
IErrorInfo->GetSource에서 반환된 문자열 |
StackTrace |
스택 추적 |
TargetSite |
실패한 HRESULT를 반환한 메서드의 이름 |
Message, Source 및 StackTrace와 같은 예외 필드는 StackOverflowException에 사용할 수 없습니다.