Article ID: 169496 - Last Review: March 2, 2005 - Revision: 3.2 INFO: Using ActiveX Data Objects (ADO) via #import in VC++This article was previously published under Q169496 On This PageSUMMARY
The #import directive in Visual C++ offers a powerful new mechanism for
manipulating OLE servers. When used with ActiveX Data Objects (ADO),
#import can simplify getting at your data. This article discusses what is
necessary to take advantage of #import with ADO.
MORE INFORMATIONBefore You Instantiate Any Classes Created by #importIt's important to initialize OLE before creating any instances of classes created by #import. For example, the following code is safe, as it declares a #import smart pointer, initializes OLE, and then instantiates the smart pointer:
Unhandled exception in [Program] (KERNEL32.DLL): 0xE06D7363 Microsoft C++ Exception. Correct Implementation of #importIt is important to invoke ADO correctly in your program, or you can have compiler errors. The following code demonstrates the correct way to use #import with Msado10.dll the MSADO15.dll:Error HandlingWith ADO, you may get an error in the HRESULT returned from an ADO method, you may get an exception raised by #import generated classes, and for either condition the ADO Errors Collection may be populated. In order to get at the Errors Collection you need a valid connection object. For more information please see the following article in the Microsoft Knowledge Base:169498
(http://support.microsoft.com/kb/169498/EN-US/
)
INFO: Extracting Error Information from ADO in VC++ with #import ADO and Dbdaoint.hAttempts to mix ADO (through #import) and either MFC DAO or the DAO SDK in the same implementation file, as follows:Generates the following six errors:
error C2011: 'EditModeEnum' : 'enum' type redefinition error C2011: 'LockTypeEnum' : 'enum' type redefinition error C2011: 'FieldAttributeEnum' : 'enum' type redefinition error C2011: 'DataTypeEnum' : 'enum' type redefinition error C2011: 'ParameterDirectionEnum' : 'enum' type redefinition error C2011: 'RecordStatusEnum' : 'enum' type redefinition
#import generates two files, Msado105.tlh and Msado15.tli off of the typelib contained within Msado15.dll. The structure of the .tlh file can be broken out as follows:
Forward References and TypedefsForward References and Typedefs are created through the use of struct __declspec(uuid("...")) on the GUID for any Dual Interface, Interface, and CoClass defined in the typelib.
...
struct __declspec(uuid("00000274-0000-0010-8000-00aa006d2ea4"))
/* dual interface */ _Connection;
...
struct __declspec(uuid("00000275-0000-0010-8000-00aa006d2ea4"))
/* interface */ ICADOConnection;
...
struct /* coclass */ Connection;
...
Smart Pointer TypeDef DeclarationsFor Interfaces and Dual Interfaces, smart pointers are declared, which greatly simplifies using the interface:... _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection)); ... _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection)); ... Type Library ItemsThis includes any enumerated types defined in the typelib, as well implementation of the smart pointers and typelib items:While you could call GetConnectionString or PutConnectionString, it is really unnecessary. Since ConnectionString is a property you would reference it as follows: The actual implementation of GetConnectionString/PutConnectionString can be found in the Msado15.tli file. When it comes time to use the Connection object in your code, you would use an instance of the smart pointer for the dual interface defined in Msado15.tlh as follows: Where pubs is an ODBC data source. #import and Explicitly Calling Release()The advantage of #import is that it takes care of AddRef, QueryInterface, and Release for you automatically. However, if you decide to start calling Release() explicitly, you can create problems for yourself.Within _com_ptr_t is a member variable, m_pInterface. As #import is a very thin wrapper, it makes no distinction with m_pInterface after the object is actually released, versus just decrementing its reference count without actually destroying the object. By explicitly calling Release()--without very explicitly calling AddRef() to balance it--#import will gladly try to release an object that doesn't exist, creating interesting side effects and crashing behavior. Best advice, you did not AddRef() it (or at least no need to), do not release it either. REFERENCES
182389
(http://support.microsoft.com/kb/182389/EN-US/
)
FILE: Adovcbm.exe ADO 1.5 with #import and Getrows/Bookmarks
184968
(http://support.microsoft.com/kb/184968/EN-US/
)
FILE: Adovcsp.exe Demonstrates Using Stored Procedures with ADO
186387
(http://support.microsoft.com/kb/186387/EN-US/
)
SAMPLE: Ado2atl.exe Returns ADO Interfaces from COM
181733
(http://support.microsoft.com/kb/181733/EN-US/
)
FILE: Adovcbtd.exe #import Using UpdateBatch and CancelBatch
166112
(http://support.microsoft.com/kb/166112/EN-US/
)
PRB: Conflict with EOF when using #import with ADO
168354
(http://support.microsoft.com/kb/168354/EN-US/
)
INFO: Underlying OLE and OLEDB Provider Errors Are Exposed Through ADO
APPLIES TO
| Article Translations
|
Back to the top
