信息: VC + + 中的 # import 通过使用 ActiveX 数据对象 (ADO)

文章翻译 文章翻译
文章编号: 169496 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

在 Visual c + + 中的 # import 指令提供了一种功能强大的新机制,用于操作 OLE 服务器。当使用 ActiveX 数据对象 (ADO),# import 可以简化获取您的数据。本文讨论了必要的操作以利用与 ADO 的 # import。

更多信息

之前您实例化任何类创建的 # import

若要创建由 # import 创建的任何的类实例之前初始化 OLE 重要的。例如对于下面的代码是安全,因为它声明了一个 # import 智能指针,初始化 OLE,然后实例化智能指针:

   // Declare smart pointer of Recordset
    _RecordsetPtr     p;

   void main( void )
   {
      // Initialize OLE.
      ::CoInitialize(NULL);

      // Instantiate smart pointer.
      HRESULT hr = p.CreateInstance( __uuidof( Recordset ) );

      ...
   }
				
然而,在下一次的代码示例是不安全的并生成未处理的异常。全局智能指针 p 是同时声明并实例化 (的传递特定的 uuid 在构造函数中):

// Declare & instantiate smart pointer of Recordset
    _RecordsetPtr     p( __uuidof( _Recordset ) );

   void main( void )
   {
      // Initialize OLE
      ::CoInitialize(NULL);

      ...
   }
				
p 是一个全局变量,因为它是实例化之前 CoInitialize 以往任何时候都称为在 main () 中。您可以使用下面的代码段来更正:
struct InitOle {
      InitOle()  { ::CoInitialize(NULL); }
      ~InitOle() { ::CoUninitialize();   }
    } _init_InitOle_;

   // Declare & instantiate smart pointer of Recordset
    _RecordsetPtr     p( __uuidof( _Recordset ) );

   ...
				
InitOle 该结构的实例声明了和实例化之前 p,并,因此,初始化 OLE 在它的构造函数中。没有这种类型的防故障中,您将看到以下错误消息:
未处理的异常在 [程序] (KERNEL32.DLL): 0xE06D7363
Microsoft c + + 的异常。

更正 # import 的实现

一定要在您的程序中正确地调用 ADO,也可以由编译器错误。下面的代码演示如何使用 # import Msado10.dll 该 MSADO15.dll 正确的方法:

   #import <msado15.dll>            \ 
   no_namespace                     \ 
  rename( "EOF", "adoEOF" )
				

错误处理

用 ADO,您可能会收到错误中从一个 ADO 方法返回的 HRESULT、 您可能会看到由 # import 生成类引发异常,可能使用 ADO 错误集合填充的任何一个条件为。若要获取错误集合必须有效的连接对象。有关详细信息,请参阅下面 Microsoft 知识库中相应的文章:

169498信息: 使用 # import 提取从 ADO VC + + 中的错误信息

ADO 和 Dbdaoint.h

试图在混合 (通过 # import) 的 ADO 和 MFC DAO 或 DAO SDK 中相同的实现文件,如下所示:

  #include <afxdao.h>  // MFC DAO
   // -or-
  #include <dbdao.h>   // DAO SDK

  #import <msado15.dll> no_namespace ...
				

生成以下六个错误:

错误 C2011: EditModeEnum: enum 键入重定义
错误 C2011: LockTypeEnum: enum 键入重定义
错误 C2011: FieldAttributeEnum: enum 键入重定义
错误 C2011: DataTypeEnum: enum 键入重定义
错误 C2011: ParameterDirectionEnum: enum 键入重定义
错误 C2011: RecordStatusEnum: enum 键入重定义
而非常几乎相同的内容,每个枚举类型中的实际值不同于什么必需的 ADO 和 DAO 通过要求。您有多个选项来解决此问题:

  • 到单独的.cpp 文件中的单独 ADO 和 DAO 代码。保留的 # import 使用或 # include <afxdao.h/dbdao.h> 以及单独的实现文件中。
  • 修改 # import 语句以创建一个命名空间的 ADO 为生成的任何内容。这意味着必须将引用 ADO 对象下面两个函数中所示时,引用命名空间。第一个演示如何使用 ADO 函数中以独占方式。 第二个显示了如何混合和匹配 ADO 和 DAO 对象。做到这一点只通过显式引用 ADO 命名空间的任何 ADO 类或枚举的类型:

       #include <afxdao.h>
    
          #import <msado15.dll>                            \ 
                  rename_namespace("AdoNS") rename( "EOF", "adoEOF" )
    
          void ADOOnly( void )
          {
              using namespace AdoNS;
    
              _RecordsetPtr   prs;
    
              // Generates Compile Errors:
              CDaoRecordset   rs;
          }
    
          void MixAdoAndDao( void )
          {
              AdoNS::_RecordsetPtr  prs;
    
              // Compiles just fine
              CDaoRecordset   drs;
          }
    						
dissecting 和使用 Msado105.tlh/Msado15.tli--------------------------------------------

# import 生成 Msado105.tlh 和关闭的类型库包含在 Msado15.dll Msado15.tli 的两个文件。.tlh 文件的结构可以划分,如下所示:
  • 向前引用和类型定义
  • 智能指针 Typedef 和声明
  • 类型库项目
下面将详细介绍了每个加载项。

向前引用和类型定义

向前引用和类型定义为任何双重接口界面,通过结构 __declspec(uuid("...")) GUID 上使用的创建和 CoClass 定义在类型库中。

   ...
   struct __declspec(uuid("00000274-0000-0010-8000-00aa006d2ea4"))
   /* dual interface */ _Connection;
   ...
   struct __declspec(uuid("00000275-0000-0010-8000-00aa006d2ea4"))
   /* interface */ ICADOConnection;
   ...
   struct /* coclass */ Connection;
   ...
				
连接,如的不是所有接口都有多个实现。 这取决于该的类型库,但对于 ADO 接口最多为双和不实现接口或 $ coclass。

智能指针 TypeDef 声明

接口和双重接口,智能指针声明,这大大简化了使用接口:
   ...
   _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
   ...
   _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection));
   ...
				
注意没有智能指针被声明为 coclass 连接接口。

类型库项目

这包括在该的类型库中定义为以及实施智能指针和类型库项目的任何枚举的类型:

enum CursorTypeEnum
   {
      adOpenUnspecified = -1,
      adOpenForwardOnly = 0,
      adOpenKeyset = 1,
      adOpenDynamic = 2,
      adOpenStatic = 3
   };

   ...

   struct __declspec(uuid("00000274-0000-0010-8000-00aa006d2ea4"))
   _Connection : _ADO
   {
      // 
      // Property data.
      // 
      _declspec(property(get=GetConnectionString,
                         put=PutConnectionString))
      _bstr_t ConnectionString;
      ...

      // 
      // Wrapper methods for error-handling.
      // 
      _bstr_t GetConnectionString ( );
      void PutConnectionString (
          _bstr_t pbstr );
      ...

      // 
      // Raw methods provided by interface.
      // 
      virtual HRESULT __stdcall get_ConnectionString (
          BSTR * pbstr ) = 0;
      virtual HRESULT __stdcall put_ConnectionString (
          BSTR pbstr ) = 0;
      ...
   };
				
前面的代码片段中属性数据部分使用 declspec 声明获取和放 ConnectionString 方法。包装方法部分提供了由 # import,创建该包装这些的方法,并引发 _com_error 异常,如果它们不是成功的方法。原始方法部分中声明由接口调用的实际方法。

虽然您可以调用 GetConnectionString 或 PutConnectionString,它是确实不必要的。因为 ConnectionString 是属性您将引用它,如下所示:

   bstrConnect = SysAllocString( L"DSN=AdoDemo;UID=admin;PWD=sa" );
   p->ConnectionString = bstrConnect;
				


Msado15.tli 文件中找不到 GetConnectionString/PutConnectionString 的实际实现。

它时在代码中使用连接对象的时间可以使用智能指针的实例,如下所示 Msado15.tlh 中定义双重接口:

   _ConnectionPtr p;
   bstrConnect
   HRESULT           hr = S_OK;
   _ConnectionPtr    pConn;

   hr = pConn.CreateInstance( __uuidof( Connection ) );

      if( !FAILED( hr ) )
         hr = pConn->Open( L"pubs", L"sa", L"" );
				


其中 pubs 是 ODBC 数据源。

# import 和显式调用 Release()

# import 的优点是它负责 AddRef、 QueryInterface,和发布为您自动。但是,如果您决定要启动显式调用 Release(),您可以为自己创建的问题。

在 _com_ptr_t 是成员变量,m_pInterface。# import 是非常细的包装,因为它可以使与 m_pInterface 没有区别对象实际释放之后,而不是它的引用计数而不实际销毁该对象的只是递减。 通过显式调用发布 ()--没有以平衡其--# import 非常明确调用 AddRef() 办理尝试释放对象没有创建有趣的副作用和崩溃的行为。

最佳的建议您进行了不 AddRef() 它 (或至少不需要),不释放它要么。

参考

  • 内部 Com 通过 Dale Rogerson ISBN 1 57231 349 8
  • 该 OLE 的 COM 对象查看器 (Oleview.exe) 随提供使用 Visual c + + 的检查类型库的内容。
  • visual c + + 的联机文档: # import 的搜索
有关更多的信息请单击下面文章编号,以查看 Microsoft 知识库中相应的文章:
182389FILE: Adovcbm.exe ADO 1.5 与 # import 和获取/书签
184968FILE: Adovcsp.exe 演示使用存储过程与 ADO
186387示例: Ado2atl.exe 返回 ADO 接口从 COM
181733FILE: Adovcbtd.exe # import 使用 UpdateBatch 和 CancelBatch
166112使用 EOF 用 ADO 使用 # import 时 PRB: 冲突
168354信息: 基础 OLE 和 OLEDB 提供程序错误公开通过 ADO

属性

文章编号: 169496 - 最后修改: 2005年3月2日 - 修订: 3.2
这篇文章中的信息适用于:
  • Microsoft ActiveX Data Objects 1.0?当用于
    • Microsoft Visual C++ 4.2 企业版
    • Microsoft Visual C++ 5.0 企业版
    • Microsoft Visual C++ 6.0 企业版
    • Microsoft Visual C++ 4.2 专业版
    • Microsoft Visual C++ 5.0 专业版
    • Microsoft Visual C++ 6.0 专业版
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 1.5?当用于
    • Microsoft Visual C++ 4.2 企业版
    • Microsoft Visual C++ 5.0 企业版
    • Microsoft Visual C++ 6.0 企业版
    • Microsoft Visual C++ 4.2 专业版
    • Microsoft Visual C++ 5.0 专业版
    • Microsoft Visual C++ 6.0 专业版
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.0?当用于
    • Microsoft Visual C++ 4.2 企业版
    • Microsoft Visual C++ 5.0 企业版
    • Microsoft Visual C++ 6.0 企业版
    • Microsoft Visual C++ 4.2 专业版
    • Microsoft Visual C++ 5.0 专业版
    • Microsoft Visual C++ 6.0 专业版
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.1?当用于
    • Microsoft Visual C++ 4.2 企业版
    • Microsoft Visual C++ 5.0 企业版
    • Microsoft Visual C++ 6.0 企业版
    • Microsoft Visual C++ 4.2 专业版
    • Microsoft Visual C++ 5.0 专业版
    • Microsoft Visual C++ 6.0 专业版
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.5?当用于
    • Microsoft Visual C++ 4.2 企业版
    • Microsoft Visual C++ 5.0 企业版
    • Microsoft Visual C++ 6.0 企业版
    • Microsoft Visual C++ 4.2 专业版
    • Microsoft Visual C++ 5.0 专业版
    • Microsoft Visual C++ 6.0 专业版
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.6?当用于
    • Microsoft Visual C++ 4.2 企业版
    • Microsoft Visual C++ 5.0 企业版
    • Microsoft Visual C++ 6.0 企业版
    • Microsoft Visual C++ 4.2 专业版
    • Microsoft Visual C++ 5.0 专业版
    • Microsoft Visual C++ 6.0 专业版
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Data Access Components 2.7
关键字:?
kbmt kbcode kbdatabase kbinfo kbusage KB169496 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 169496
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com