How to replace #import's exception raising mechanism for ActiveX Data Objects (ADO) in Visual C++ (177425)
The information in this article applies to:
- Microsoft Visual C++, 32-bit Enterprise Edition 5.0
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 5.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 6.0
- Microsoft Visual C++ 2005 Express Edition
- Microsoft Visual C++ .NET (2003)
- Microsoft Visual C++ .NET (2002)
This article was previously published under Q177425 Note Microsoft Visual C++ .NET 2002 and Microsoft Visual C++ .NET 2003 support both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model. The information in this article applies only to unmanaged Visual C++ code. Microsoft Visual C++ .NET 2005 supports both the
managed code model that is provided by the Microsoft .NET Framework and the
unmanaged native Microsoft Windows code model. SUMMARY Using the #import statement to create your client
application introduces exception handling through the _com_error exception
class when a wrapper for an object's method encounters a failed HRESULT. You
might have valid reasons to replace this mechanism with your own
implementation. MORE INFORMATION There are two ways to use #import and not have it raise
exceptions for failed HRESULTS. The first is simply to use the
raw_interfaces_only clause with the #import statement. However, this negates
some of the advantages of the wrapper classes that #import provides.
The second technique is by providing your own implementation for
_com_raise_error, which has the following prototype and default
implementation:
void __stdcall _com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0)
throw(_com_error);
void __stdcall
_com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0) throw(_com_error)
{
throw _com_error(hr, perrinfo);
}
This function is declared but not implemented in the Comdef.h file. If
you provide your own implementation in an .OBJ file, the linker uses that
implementation as opposed to bringing it in from the Comsupp.lib file.
_com_raise_error exists in its own object in the Comsupp.lib file so it can be
easily replaced by your code. Following is a sample implementation of
the #import's exception raising function. NOTE: Currently the compiler ignores a function
exception-specification and generates the following warning: warning C4290: C++ Exception Specification ignored. At
this time, the implementation details of exception specification have not been
standardized, and are accepted but not implemented in Microsoft Visual C++.
Code compiled with ignored exception specifications may need to be recompiled
and linked to be reused in future versions supporting exception specifications.
You can avoid this warning by using the warning pragma:
#pragma warning( disable : 4290 )
Sample Code
void __stdcall
_com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0) throw(_com_error)
{
//This message box is for demonstration purpose only.
AfxMessageBox( "_com_raise_error (HRESULT, IErrorInfo*)" );
//Your own error handling code or just an abort.
}
#import <msado15.dll>
...
_bstr_t bstrEmpty(L"");
_ConnectionPtr Conn1 = NULL;
Conn1.CreateInstance( __uuidof( Connection ) );
Conn1->Open( bstrEmpty, bstrEmpty, bstrEmpty );
This code attempts to open an ActiveX Data Objects (ADO) connection
object without providing any valid connection information. Replacing
_com_raise_error prevented the _com_error from being raised.
Modification Type: | Major | Last Reviewed: | 1/11/2006 |
---|
Keywords: | kbhowto kbCompiler kbDatabase kbinfo kbMDACNoSweep KB177425 kbAudDeveloper |
---|
|