COM <-> .Net Exception handling

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;
}
 
C

Carl Daniel [VC++ MVP]

Mark said:
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).

What compiler are you using? I don't havbe VC7 (VS.NET 2003) installed, but
this example compiled and ran fine with VC 7.1 (VS.NET 2003). (I also
changed the #import to refer to the 1.1 framework).

-cd
 
C

Carl Daniel [VC++ MVP]

Mark said:
Hi Carl,

cl /? displays - Microsoft (R) 32-bit C/C++ Optimizing Compiler
Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

The about box of Visual Studio says Version 7.1.3088 of the
Development Environment and Version 1.1.4322 of the framework.

Well, that's VC7.1, and the example you posted compiled & ran fine for me
using that version. You're encountering something "strange". Anything else
that might be unique (or less common) about your development environment?
What OS are you using?

-cd
 
G

Guest

I am compiling on XP Professional Version 2002 Service Pack 1. I have both .Net 1.0 and 1.1 installed but i know the typlelib being loaded is the one referenced in the source file

The machice is an IBM Thinkpad and it has 1gb of memory

When you do cl /? do you also get Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86? This version number isn't obviously related to VS version 7.1.
 
C

Carl Daniel [VC++ MVP]

Mark said:
I am compiling on XP Professional Version 2002 Service Pack 1. I
have both .Net 1.0 and 1.1 installed but i know the typlelib being
loaded is the one referenced in the source file.

The machice is an IBM Thinkpad and it has 1gb of memory.

When you do cl /? do you also get Microsoft (R) 32-bit C/C++
Optimizing Compiler Version 13.10.3077 for 80x86? This version
number isn't obviously related to VS version 7.1.

Yes, that's the same version, and the same OS - XP Pro SP1. I too have .NET
1.0 and 1.1 installed, yet the example worked perfectly for me.

cl version 13.10 = VC version 7.10 (VC1 was cl version 7.00).

Hmm. I'm out of ideas at the moment.

-cd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top