如何在没有 MFC 的情况下使用 Visual C++ 中的 DAO






3.29/5 (6投票s)
使用 #import 指令并发现 DAO 类型库。
引言
如果您曾经在 Visual Basic 和使用 MFC 的 Visual C++ 中使用过数据访问对象 (DAO),您一定注意到,在 Visual Basic 中,操作 Microsoft Access MDB 文件比在带有 MFC 的 Visual C++ 中更令人愉快。而且,您一定想过是否存在一种解决方法,使在 Visual C++ 中使用 MDB 的灵活性与在 Visual Basic 中一样。
为了解决这个问题,让我们尝试在 Visual C++ 中使用与 Visual Basic 相同的方式。这种方式假定您应该直接使用类型库。与更适合快速应用程序开发并具有访问类型库自身方法的 Visual Basic 不同,在 Visual C++ 中,通过使用 #import
指令将类型库的内容转换为 C++ 类来操作类型库更为可取。
理解这一点最好的方法是阅读一个示例源代码
// daocpp.cpp // Describe the full path to dao360.dll file. Interface files dao360.tlh and // dao360.tli will be generated automatically during compilation. // The #import directive creates "DAO" namespace to avoid name conflicts with // other libraries. So, all DAO members must be referenced with "DAO::" prefix, // e.g. DAO::DBEngine #import <C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll> #include <stdio.h> #include <tchar.h> // The following procedure dump_com_error and structure StartOle are borrowed from // MSDN samples. // Dump all COM errors to console void dump_com_error(_com_error &e) { _tprintf(_T("Oops - hit an error!\n")); _tprintf(_T("\tCode = %08lx\n"), e.Error()); _tprintf(_T("\tCode meaning = %s\n"), e.ErrorMessage()); _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); _tprintf(_T("\tSource = %s\n"), (LPCTSTR) bstrSource); _tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription); } // If this is placed in the scope of the smart pointers, they must be // explicitly Release(d) before CoUninitialize() is called. If any reference // count is non-zero, a protection fault will occur. struct StartOle { StartOle() { CoInitialize(NULL); } ~StartOle() { CoUninitialize(); } } _inst_StartOle; // From this line everything will be commented with its VB analogue void main() { // Dim Dbe As DBEngine DAO::_DBEnginePtr Dbe(__uuidof(DAO::DBEngine)); // Dim CurrDB As Database DAO::DatabasePtr CurrDB; // Dim stmp As String char stmp[1024]; // wide chars not used here for simplicity // (COM errors must be handled by C++ try/catch block) try { // Dbe.CreateDatabase("test.mdb", ";LANGID=0x0419;CP=1251;COUNTRY=7;", // dbVersion40). // (";COUNTRY=7" expression allows using "dd.mm.yy" date format in queries. // dbVersion40 constant creates a database with Access 2000 file format. // The value for Access 97 format is dbVersion30) CurrDB = Dbe->CreateDatabase("test.mdb", ";LANGID=0x0419;CP=1251;COUNTRY=7;", _variant_t((short) DAO::dbVersion40)); // Set CurrDB = Dbe.OpenDatabase("test.mdb") CurrDB = Dbe->OpenDatabase("test.mdb"); // stmp = "CREATE TABLE ....." strcpy(stmp,"CREATE TABLE Test ( \ ARTIST Char(40), \ TITLE1 Char(60), \ FORMAT1 Char(9), \ CATNO Numeric, \ PRICE Numeric, \ DATEIN DateTime, \ NOTES Char(10) \ );"); // CurrDB.Execute(stmp) CurrDB->Execute(stmp); // stmp = "INSERT INTO ....." strcpy(stmp,"INSERT INTO Test VALUES( \ \"Artist\", \ \"Title\", \ \"Format1\", \ 1223, \ 3231.54, \ '21.09.04', \ \"Notes\" \ );"); // CurrDB.Execute(stmp) CurrDB->Execute(stmp); // for i=0 to CurrDB.TableDefs.Count // (for all tables in database including system tables) for (int i=0; i < CurrDB->TableDefs->Count; i++) { // Debug.Print CurrDB.TableDefs(i).Name _variant_t vI = _variant_t((long) i); printf("%s\n", (char *) CurrDB->TableDefs->Item[vI]->Name); } } catch(_com_error &e) { dump_com_error(e); } }
在命令行中编译此示例,如下所示:
cl -GX daocpp.cpp
并运行 daocpp.exe。数据库文件 test.mdb 将被创建。该文件将包含表 Test,其中包含一条数据记录。
如您所见,在合并类型库中的信息后,类型 DBEngine
和 Database
被映射到 C++ 类 DAO::_DBEnginePtr
和 DAO::DatabasePtr
。类型 TableDef
将被映射到 _TableDefPtr
。
注意:使用 DAO 需要将 C++ 类型转换为变体类型。在本示例中,您可以看到 C++ 类型 long
被转换为类型 _variant_t
_variant_t vI = _variant_t((long) i);
同样,例如,bool
类型的逻辑值 True
和 False
将被转换为类型 _variant_t
,如下所示:
_variant_t vTrue = _variant_t((bool) -1); _variant_t vFalse = _variant_t((bool) 0);
我希望这篇文章能帮助您在应用程序中编写更高效的代码。