INFO: Replacing #import's Exception Raising Mechanism for ADOLast reviewed: March 11, 1998Article ID: Q177425 |
The information in this article applies to:
SUMMARYUsing 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 INFORMATIONThere 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. Below is an example 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.According to C++ WP, if any declaration of a function has an exception- specification, all declarations, including the definition, of that function shall have an exception-specification with the same set of type-ids.
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 "C:\Program Files\Common Files\System\ado\msado10.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. Although the function has been replaced, you may still need to trap for exceptions. Consider the code snippet below:
#import "C:\Program Files\Common Files\System\ado\msado10.dll" ... ... _ConnectionPtr Conn1 = NULL; // Conn1.CreateInstance( __uuidof( Connection ) ); Conn1->Open( bstrEmpty, bstrEmpty, bstrEmpty );In this case, Conn1 is not a valid object, and the interface pointer to this non-existent object is NULL, resulting in _com_raise_error being called. However, the overloaded -> operator method returns a null interface through which the compiler then attempts to invoke the Open() method, resulting in a Win32 exception. Testing Conn1 for NULL before calling Open() prevents this exception. Keywords : CLIss Version : WINNT:5.0 Platform : winnt Issue type : kbinfo |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |