G
Guest
I have a COM object that calls into a C# Forms library. The library can throw exceptions and I want to handle the exceptions in COM. Adam Nathan wrote a Microsoft sponsored book titled .Net and Com the complete interoperability guide which shows examples of how to do this.
Below please find the book example code for getting extended error information from a V-Table bound .Net component. This code does not compile because the compiler gives a C1001 (Internal Compiler Error)
If I remove the #import for mscorlib.tlb no_namespace named_guids then the compiler does not complain but I can no longer access _Exception and other interfaces which are referenced in the core lib type library. I have also tried changing the import to a later version of the type lib
Is there a way to reliably pass exceptions between the 2 worlds
Mar
---------------------------------------------------------- Example (it is supposed to build wtih cl filename)----------------------------------------------------------------------------------
#define _WIN32_DCO
#include <stdio.h
#include <wtypes.h
#import "c:\\Windows\\Microsoft.NET\\Framework\\v1.0.3705\\mscorlib.tlb" no_namespace named_guids raw_interfaces_onl
int main(int argc, char* argv[]
IUnknown* pUnk = NULL
IList* pList = NULL
ISupportErrorInfo* pSuppErrInfo = NULL
IErrorInfo* pErrInfo = NULL
_Exception* pException = NULL
_Type* pType = NULL
HRESULT hresult
// Initialize CO
hresult = CoInitializeEx(NULL, COINIT_MULTITHREADED)
if (FAILED(hresult))
printf("ERROR: Cannot initialize COM: 0x%x\n", hresult)
return -1
// Instantiate the System.Collections.ArrayList clas
hresult = CoCreateInstance(CLSID_ArrayList, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown, (void **)&pUnk)
if (FAILED(hresult))
{
printf("ERROR: Cannot create object: 0x%x\n", hresult)
return -1
// Get the IList interfac
hresult = pUnk->QueryInterface(IID_IList, (void**)&pList)
if (FAILED(hresult))
{
printf("ERROR: Cannot obtain the IList interface pointer: 0x%x\n"
hresult)
pUnk->Release()
return -1
hresult = pList->RemoveAt(1)
if (FAILED(hresult))
{
printf("ERROR: RemoveAt failed: 0x%x\n\n", hresult)
// Check if the object supports extended error informatio
hresult = pList->QueryInterface(IID_ISupportErrorInfo
(void**)&pSuppErrInfo)
if (SUCCEEDED(hresult)
hresult = pSuppErrInfo->InterfaceSupportsErrorInfo(IID_IList)
if (hresult == S_OK)
// Attempt to get the IErrorInfo pointe
hresult = GetErrorInfo(0, &pErrInfo)
if (SUCCEEDED(hresult)
BSTR source = NULL
BSTR description = NULL
BSTR helpFile = NULL
unsigned long helpContext
hresult = pErrInfo->GetSource(&source)
if (SUCCEEDED(hresult)) printf("Source: %S\n\n",
source)
hresult = pErrInfo->GetDescription(&description)
if (SUCCEEDED(hresult)) printf("Description: %S\n\n"
description)
hresult = pErrInfo->GetHelpFile(&helpFile)
if (SUCCEEDED(hresult)) printf("HelpFile: %S\n\n",
helpFile)
hresult = pErrInfo->GetHelpContext(&helpContext)
if (SUCCEEDED(hresult)) printf("HelpContext: %d\n\n"
helpContext)
if (source != NULL) SysFreeString(source)
if (description != NULL) SysFreeString(description)
if (helpFile != NULL) SysFreeString(helpFile)
// Call members of the .NET exception objec
BSTR stackTrace = NULL
BSTR toString = NULL
BSTR exceptionTypeName = NULL
hresult = pErrInfo->QueryInterface(IID__Exception
(void**)&pException)
if (SUCCEEDED(hresult)
hresult = pException->get_StackTrace(&stackTrace)
if (SUCCEEDED(hresult)) printf("Stack Trace: %S\n\n",
stackTrace)
hresult = pException->get_ToString(&toString)
if (SUCCEEDED(hresult)) printf("ToString: %S\n\n",
toString);
hresult = pException->GetType(&pType);
if (SUCCEEDED(hresult))
{
hresult = pType->get_ToString(&exceptionTypeName);
if (SUCCEEDED(hresult)) printf("Exception Type: %S\n\n",
exceptionTypeName);
}
if (toString != NULL) SysFreeString(toString);
if (stackTrace != NULL) SysFreeString(stackTrace);
if (exceptionTypeName != NULL)
SysFreeString(exceptionTypeName);
}
}
}
}
}
// Release interface pointers
if (pUnk != NULL) pUnk->Release();
if (pList != NULL) pList->Release();
if (pSuppErrInfo != NULL) pSuppErrInfo->Release();
if (pErrInfo != NULL) pErrInfo->Release();
if (pException != NULL) pException->Release();
if (pType != NULL) pType->Release();
CoUninitialize();
return 0;
}
Below please find the book example code for getting extended error information from a V-Table bound .Net component. This code does not compile because the compiler gives a C1001 (Internal Compiler Error)
If I remove the #import for mscorlib.tlb no_namespace named_guids then the compiler does not complain but I can no longer access _Exception and other interfaces which are referenced in the core lib type library. I have also tried changing the import to a later version of the type lib
Is there a way to reliably pass exceptions between the 2 worlds
Mar
---------------------------------------------------------- Example (it is supposed to build wtih cl filename)----------------------------------------------------------------------------------
#define _WIN32_DCO
#include <stdio.h
#include <wtypes.h
#import "c:\\Windows\\Microsoft.NET\\Framework\\v1.0.3705\\mscorlib.tlb" no_namespace named_guids raw_interfaces_onl
int main(int argc, char* argv[]
IUnknown* pUnk = NULL
IList* pList = NULL
ISupportErrorInfo* pSuppErrInfo = NULL
IErrorInfo* pErrInfo = NULL
_Exception* pException = NULL
_Type* pType = NULL
HRESULT hresult
// Initialize CO
hresult = CoInitializeEx(NULL, COINIT_MULTITHREADED)
if (FAILED(hresult))
printf("ERROR: Cannot initialize COM: 0x%x\n", hresult)
return -1
// Instantiate the System.Collections.ArrayList clas
hresult = CoCreateInstance(CLSID_ArrayList, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown, (void **)&pUnk)
if (FAILED(hresult))
{
printf("ERROR: Cannot create object: 0x%x\n", hresult)
return -1
// Get the IList interfac
hresult = pUnk->QueryInterface(IID_IList, (void**)&pList)
if (FAILED(hresult))
{
printf("ERROR: Cannot obtain the IList interface pointer: 0x%x\n"
hresult)
pUnk->Release()
return -1
hresult = pList->RemoveAt(1)
if (FAILED(hresult))
{
printf("ERROR: RemoveAt failed: 0x%x\n\n", hresult)
// Check if the object supports extended error informatio
hresult = pList->QueryInterface(IID_ISupportErrorInfo
(void**)&pSuppErrInfo)
if (SUCCEEDED(hresult)
hresult = pSuppErrInfo->InterfaceSupportsErrorInfo(IID_IList)
if (hresult == S_OK)
// Attempt to get the IErrorInfo pointe
hresult = GetErrorInfo(0, &pErrInfo)
if (SUCCEEDED(hresult)
BSTR source = NULL
BSTR description = NULL
BSTR helpFile = NULL
unsigned long helpContext
hresult = pErrInfo->GetSource(&source)
if (SUCCEEDED(hresult)) printf("Source: %S\n\n",
source)
hresult = pErrInfo->GetDescription(&description)
if (SUCCEEDED(hresult)) printf("Description: %S\n\n"
description)
hresult = pErrInfo->GetHelpFile(&helpFile)
if (SUCCEEDED(hresult)) printf("HelpFile: %S\n\n",
helpFile)
hresult = pErrInfo->GetHelpContext(&helpContext)
if (SUCCEEDED(hresult)) printf("HelpContext: %d\n\n"
helpContext)
if (source != NULL) SysFreeString(source)
if (description != NULL) SysFreeString(description)
if (helpFile != NULL) SysFreeString(helpFile)
// Call members of the .NET exception objec
BSTR stackTrace = NULL
BSTR toString = NULL
BSTR exceptionTypeName = NULL
hresult = pErrInfo->QueryInterface(IID__Exception
(void**)&pException)
if (SUCCEEDED(hresult)
hresult = pException->get_StackTrace(&stackTrace)
if (SUCCEEDED(hresult)) printf("Stack Trace: %S\n\n",
stackTrace)
hresult = pException->get_ToString(&toString)
if (SUCCEEDED(hresult)) printf("ToString: %S\n\n",
toString);
hresult = pException->GetType(&pType);
if (SUCCEEDED(hresult))
{
hresult = pType->get_ToString(&exceptionTypeName);
if (SUCCEEDED(hresult)) printf("Exception Type: %S\n\n",
exceptionTypeName);
}
if (toString != NULL) SysFreeString(toString);
if (stackTrace != NULL) SysFreeString(stackTrace);
if (exceptionTypeName != NULL)
SysFreeString(exceptionTypeName);
}
}
}
}
}
// Release interface pointers
if (pUnk != NULL) pUnk->Release();
if (pList != NULL) pList->Release();
if (pSuppErrInfo != NULL) pSuppErrInfo->Release();
if (pErrInfo != NULL) pErrInfo->Release();
if (pException != NULL) pException->Release();
if (pType != NULL) pType->Release();
CoUninitialize();
return 0;
}