Contents:
- 1 °ü·Ã¼Àû
- 2 Referencing ActiveX Data Objects
- ADO: ActiveX Data Objects
- Jason T. Roff Àú, O'Reilly
2 Referencing ActiveX Data Objects #
Visual C++ ¿¡¼ #import Áö½Ã¾î¸¦ »ç¿ëÇϸé ŸÀÔ ¶óÀ̺귯¸® ( Type Library ) ¿¡ Æ÷ÇÔµÈ Á¤º¸¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. µû¶ó¼ ´ÙÀ½°ú °°ÀÌ #import Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ADO ¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù.
#import <msado15.dll> no_namespace rename( "EOF", "EOFile" )
msado15.dll ÆÄÀÏÀÇ °æ·Î ( ÀϹÝÀûÀ¸·Î C:\Program Files\Common Files\System\ado ) ´Â Visual C++ ȯ°æ¿¡ ¼³Á¤µÇ¾î ÀÖ¾î¾ß ÇÏ¸ç ¼³Á¤µÇ¾î ÀÖÁö ¾ÊÀ» °æ¿ì Visual Studio ÀÇ [ Tools ] - [ Options ] ¸Þ´º¸¦ ¼±ÅÃÇÏ¿© [ Directories ] ÅÇÀ» ¼±ÅÃÈÄ [ Library files ] ¿¡ °æ·Î¸¦ Ãß°¡ÇÑ´Ù.
#import Áö½Ã¾î´Â ´ÙÀ½°ú °°ÀÌ µÎ °¡Áö ÀÛ¾÷À» ¼öÇàÇÑ´Ù.
- .tlh È®ÀåÀÚ¸¦ °®´Â ŸÀÔ ¶óÀ̺귯¸® Çì´õ ( Type Library Header ) ÆÄÀÏÀ» »ý¼ºÇÑ´Ù.
msado15.dll ÆÄÀÏÀÇ Å¸ÀÔ ¶óÀ̺귯¸®¿¡ Æ÷ÇÔµÈ ¿ÀºêÁ§Æ® Á¤ÀÇ¿Í µ¥ÀÌŸ ŸÀÔÀ» ³ª¿Çϰí ÀÖ´Ù.
- .tli ( Type Library Implementation ) È®ÀåÀÚ¸¦ °®´Â ÆÄÀÏÀ» »ý¼ºÇÑ´Ù.
msado15.dll ÆÄÀÏÀÇ Å¸ÀÔ ¶óÀ̺귯¸®¿¡ Á¤ÀÇµÈ ¿ÀºêÁ§Æ® ¸ðµ¨ÀÇ ·¡ÆÛ ÇÔ¼ö ( Wrapper Function ) ¸¦ Æ÷ÇÔÇϰí ÀÖ´Ù.
#import Áö½Ã¾îÀÇ
rename ¼Ó¼ºÀº
rename( "EOF", "EOFile" )
ŸÀÔ ¶óÀ̺귯¸®¿¡ Æ÷ÇÔµÈ EOF Ű¿öµå¸¦ EOFile ·Î º¯°æÇÑ´Ù. À̰ÍÀº Visual C++ ¿¡ Á¤ÀÇµÈ EOF ¼Ó¼º ( Property ) °ú Ãæµ¹À» ÇÇÇϱâ À§Çؼ »ç¿ëµÈ´Ù.
3 Creating ActiveX Data Objects #
ActiveX Data Object ¸¦ »ç¿ëÇÏ´Â °ÍÀº OLD DB ¸¦ »ç¿ëÇÏ´Â °Í°ú ºñ½ÁÇÏ´Ù. À̰ÍÀº OLE DB ±â¼úÀ» °£´ÜÈ÷ ·¡ÇÎ ( Wrapping ) ÇÑ °ÍÀÌ ADO À̱⠶§¹®ÀÌ´Ù.
We do this with the following piece of code:
struct StartOLEProcess
{
StartOLEProcess()
{
::CoInitialize( NULL );
}
~StartOLEProcess()
{
::CoUninitialize();
}
} _start_StartOLEProcess;
ÀÌ ±¸Á¶Ã¼´Â
Placing this structure definition anywhere in our application forces the application to call the _start_StartOLEProcess constructor once it has started.
»ý¼ºÀÚ´Â CoInitialize() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© OLE ¸¦ ÃʱâÈÇÑ´Ù. ¼Ò¸êÀÚ¿¡¼ CoUninitialize() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© OLE ¸¦ Á¤Áö½ÃŲ´Ù.
This constructor simply calls CoInitialize to initialize OLE. Once our application is complete, the destructor of _start_StartOLEProcess will be called. This in turn will call CoUninitialize, which will shut down OLE.
The next thing we must do to create an ActiveX Data Object is to declare a pointer to the object we wish to create, as follows:
// define a variable that will be used as a reference to the
// Connection object and set it to NULL
ADODB::_ConnectionPtr con = NULL;
// define a variable that will be used as a reference to the
// Recordset object and set it to NULL
ADODB::_RecordsetPtr rst = NULL;
We then can create an ActiveX Data Object by calling the CreateInstance function of our ADO pointer. This function returns a result of type HRESULT to inform us whether the creation of the object was successful. This is illustrated in the following code fragment:
' create a new instance of an ADO Connection object
hr = con.CreateInstance( __uuidof( ADODB::Connection ) );
' create a new instance of an ADO Recordset object
hr = rst.CreateInstance( __uuidof( ADODB::Recordset ) );
Finally, just as in Visual Basic, it is always a good idea to release objects once they are no longer needed. In Visual C++, we accomplish this with a couple of lines of code that look like the following:
' remove the objects
con = NULL;
rst = NULL;
4 Using ADO with Visual C++: An Example #
Now let's take a look at a fully functional example of a Visual C++ application that utilizes ActiveX Data Objects. To try the following code, create a new Win32 Console Application from within Visual C++, choosing the Simple option from the wizard, and replace the contents of the main .cpp file with the code shown in Example 3-2.
Remember, just as with the Visual Basic example, make sure that a copy of Biblio.mdb is in the C:\Program Files\Microsoft Visual Studio\VB98 directory, or that you change the directory in the following source code to reflect the proper path of the Access database. In addition, if you are having trouble with this code, make sure that you have the MSADO15.DLL file in the C:\Program Files\Common Files\System\ado directory or that you have the proper directory entered in the source code.
Example 3-2. A Simple Visual C++ Example
#include "stdafx.h"
#include <stdio.h>
#import "C:\Program Files\Common Files\System\ado\MSADO15.dll" rename( "EOF", "EOFile" )
struct StartOLEProcess
{
StartOLEProcess()
{
::CoInitialize(NULL);
}
~StartOLEProcess()
{
::CoUninitialize();
}
} _start_StartOLEProcess;
void main( void )
{
// define our variables which will be used as references to the
// Connection and Recordset objects
ADODB::_ConnectionPtr con = NULL;
ADODB::_RecordsetPtr rec = NULL;
// define variables to read the Author field from the recordset
ADODB::FieldPtr pAuthor;
_variant_t vAuthor;
char sAuthor[ 40 ];
// create two strings for use with the creation of a Connection
// and a Recordset object
bstr_t sConString;
bstr_t sSQLString;
// create a variable to hold the result to function calls
HRESULT hr = S_OK;
// long variable needed for Execute method of Connection object
VARIANT *vRecordsAffected = NULL;
// create a new instance of an ADO Connection object
hr = con.CreateInstance( __uuidof( ADODB::Connection ) );
printf( "Connection object created.\n" );
// open the BiblioDSN data source with the Connection object
sConString = L"Provider=Microsoft.Jet.OLEDB.4.0; "
L"Data Source=C:\\Program Files\\"
L"Microsoft Visual Studio\\"
L"VB98\\Biblio.mdb";
con->Open( sConString, L"", L"", -1 );
printf( "Connection opened.\n" );
// create a Recordset object from a SQL string
sSQLString = L"SELECT TOP 10 Author FROM Authors;";
rec = con->Execute( sSQLString,
vRecordsAffected,
1 );
printf( "SQL statement processed.\n" );
// point to the Author field in the recordset
pAuthor = rec->Fields->GetItem( "Author" );
// retrieve all the data within the Recordset object
printf( "Getting data now...\n\n" );
while( !rec->EOFile )
{
// get the Author field's value and change it
// to a multibyte type
vAuthor.Clear();
vAuthor = pAuthor->Value;
WideCharToMultiByte( CP_ACP,
0,
vAuthor.bstrVal,
-1,
sAuthor,
sizeof( sAuthor ),
NULL,
NULL );
printf( "%s\n", sAuthor );
rec->MoveNext();
}
printf( "\nEnd of data.\n" );
// close and remove the Recordset object from memory
rec->Close();
rec = NULL;
printf( "Closed an removed the "
"Recordset object from memory.\n" );
// close and remove the Connection object from memory
con->Close();
con = NULL;
printf( "Closed and removed the "
"Connection object from memory.\n" );
}
Although much of the previous example will be very foreign to you until you have a thorough understanding of how to develop applications with ActiveX Data Objects, it is particularly important to notice how Visual C++ applications must convert datatypes returned by a field's value. In Example 3-2, a function called WideCharToMultiByte is used to convert a Variant datatype to a normal char string datatype (ASCII) so that it can in turn be passed to the printf function.