INFO: Usando ActiveX Data Objects (ADO) via # Import no VC ++

Traduções deste artigo Traduções deste artigo
ID do artigo: 169496 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

A diretiva # import no Visual C++ oferece um novo mecanismo eficiente para manipular servidores OLE. Quando usado com o ActiveX Data Objects (ADO), # Import pode simplificar obter seus dados. Este artigo descreve o que é necessário para tirar proveito de # import com o ADO.

Mais Informações

Antes de instanciar qualquer classes criado por # Import

É importante ao inicializar OLE antes de criar quaisquer instâncias de classes criadas por # Import. Por exemplo, o código a seguir é seguro, que declara um ponteiro inteligente # Import, inicializa OLE e, em seguida, instancia o ponteiro inteligente:

   // Declare smart pointer of Recordset
    _RecordsetPtr     p;

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

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

      ...
   }
				
Próximo exemplo de código, no entanto, não é seguro e gera uma exceção não tratada. O ponteiro inteligente global p é tanto declarado e instanciado (devido passando um uuid específico no construtor):

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

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

      ...
   }
				
Porque p é uma variável global, ele é instanciado antes CoInitialize já é chamado no main(). Você pode corrigir isso com o seguinte trecho de código:
struct InitOle {
      InitOle()  { ::CoInitialize(NULL); }
      ~InitOle() { ::CoUninitialize();   }
    } _init_InitOle_;

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

   ...
				
Uma instância da estrutura InitOle é declarada e instanciado antes de p e, portanto, inicializa OLE no construtor é. Sem esse tipo de à prova de falhas, você verá a seguinte mensagem de erro:
Exceção no programa de [] (Kernel32.dll) sem tratamento: 0xE06D7363
Exceção do Microsoft C++.

Implementação correta de # import

É importante invocar ADO corretamente no seu programa, ou você pode ter erros do compilador. O código a seguir demonstra a maneira correta de usar # Import com Msado10.dll o MSADO15.dll:

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

Tratamento de erros

Com o ADO, você pode receber um erro no HRESULT retornado de um método do ADO, você pode receber uma exceção gerada por classes # Import gerado e a coleção de erros de ADO para qualquer condição pode ser preenchida. Para obter a coleção de erros você precisa de um objeto de conexão válida. Para obter mais informações consulte o seguinte artigo na Base de dados de Conhecimento da Microsoft:

169498INFO: Extraindo informações de erro do ADO no VC ++ com # Import

ADO e Dbdaoint.h

Tenta misturar ADO (através de # import) e MFC DAO ou o SDK do DAO no mesmo arquivo de implementação, da seguinte maneira:

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

  #import <msado15.dll> no_namespace ...
				

Gera os seguintes seis erros:

Erro C2011: 'EditModeEnum': 'enum' digite redefinição
Erro C2011: 'LockTypeEnum': 'enum' digite redefinição
Erro C2011: 'FieldAttributeEnum': 'enum' digite redefinição
Erro C2011: 'DataTypeEnum': 'enum' digite redefinição
Erro C2011: 'ParameterDirectionEnum': 'enum' digite redefinição
Erro C2011: 'RecordStatusEnum': 'enum' digite redefinição
Enquanto o muito quase idênticas em conteúdo, os valores reais em cada tipo enumerado diferem entre o que é exigido pelo ADO e o que é exigido pelo DAO. Você tem várias opções para solucionar esse problema:

  • Código DAO e ADO separado em arquivos .cpp separado. Mantenha o uso de # Import ou # include <afxdao.h/dbdao.h> em arquivos de implementação separada também.
  • Modificar a instrução # import para criar um espaço para nome para qualquer coisa gerado para ADO. Isso significa que você terá que referenciar o namespace ao fazer referência um objeto ADO conforme as duas funções abaixo. O primeiro mostra como usar o ADO exclusivamente dentro de uma função. O segundo mostra como objetos DAO e ADO combinação e correspondência. Isso é possível apenas pela referência explicita o namespace do ADO para qualquer classe do ADO ou o tipo enumerado:

       #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;
          }
    						
Msado105.tlh/Msado15.tli dissecting e usando--------------------------------------------

# Import gera dois arquivos, Msado105.tlh e Msado15.tli da typelib contido MSADO15.dll. A estrutura do arquivo .TLH pode ser dividida da seguinte maneira:
  • Encaminhar referências e definições de tipo
  • TypeDef ponteiro inteligente e declarações
  • Itens de biblioteca de tipo
Cada um é descrita detalhadamente abaixo.

Encaminhar referências e definições de tipo

Referências e definições de tipo direta são criadas através do uso de struct __declspec(uuid("...")) no GUID para qualquer dual interface, interface, e CoClass definidos no 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;
   ...
				
Nem todas as interfaces, como conexão, tem várias implementações. Isso depende da biblioteca de tipos, mas para ADO maioria das interfaces são duplo e não implementado como coclass ou interface.

Declaração de TypeDef ponteiro inteligente

Para interfaces e interfaces dual, ponteiros inteligentes são declarados, que simplifica muito usando a interface:
   ...
   _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
   ...
   _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection));
   ...
				
Observe que nenhum ponteiro inteligente foi declarado para a interface conexão coclass.

Itens de biblioteca de tipo

Isso inclui qualquer tipos enumerados definidos em typelib, como bem implementação dos ponteiros inteligentes e itens de typelib:

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;
      ...
   };
				
O fragmento de código anterior, a seção de dados de propriedade usa declspec para declarar get e coloque métodos de ConnectionString. A seção de métodos de invólucro fornece métodos criados pelo # Import, que dispor desses métodos e gerar uma exceção _com_error se eles não forem bem-sucedidos. A seção métodos RAW declara o método real que é chamado pela interface.

Enquanto você poderia chamar GetConnectionString ou PutConnectionString, não é realmente necessário. Como ConnectionString é uma propriedade você faria referência a ele da seguinte maneira:

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


A implementação real do GetConnectionString/PutConnectionString pode ser encontrada no arquivo Msado15.tli.

Quando se trata de tempo para usar o objeto de conexão em seu código, você usaria uma instância do ponteiro inteligente para a interface dupla definida no Msado15.tlh, como a seguir:

   _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"" );
				


Onde pubs é uma fonte de dados ODBC.

# Import e chamada Release() explicitamente

A vantagem de # import é que ele se encarrega de AddRef, QueryInterface e Release para você automaticamente. No entanto, se você decidir iniciar chamada Release() explicitamente, você pode criar problemas para si mesmo.

Em _com_ptr_t é m_pInterface de variável, um membro. Como # Import é um wrapper muito estreito, ele não faz distinção com m_pInterface após o o objeto é, na verdade, lançamento, versus apenas diminuindo sua referência contar sem realmente destruir o objeto. Chamando explicitamente versão ()--sem muito explicitamente chamada AddRef() para equilibrar it--# Import gladly tentará liberar um objeto que não existe, criação de efeitos colaterais interessantes e comportamento de falha.

As sugestões, você fez não AddRef() (ou pelo menos não precise), não liberá-lo ou.

Referências

  • Interno Com por Dale Rogerson ISBN 1-57231-349-8
  • O OLE COM objeto Viewer (Oleview.exe), que é fornecido com o Visual C++ para examinar o conteúdo de um typelib.
  • Documentação online do Visual C++: pesquisa na # Import
Para obter informações adicionais, clique nos números abaixo para ler os artigos na Base de dados de Conhecimento da Microsoft:
182389ARQUIVO: Adovcbm.exe ADO 1.5 com # Import e getrows/indicadores
184968FILE: Adovcsp.exe demonstra o uso de procedimentos com o ADO armazenados
186387EXEMPLO: Ado2atl.exe retorna ADO interfaces de COM
181733FILE: # Import Adovcbtd.exe usando UpdateBatch e CancelBatch
166112PROBLEMA: Conflito com o EOF ao usar o # Import com ADO
168354INFO: OLE subjacentes e erros de provedor OLEDB são expostos por meio do ADO

Propriedades

ID do artigo: 169496 - Última revisão: quarta-feira, 2 de março de 2005 - Revisão: 3.2
A informação contida neste artigo aplica-se a:
  • Microsoft ActiveX Data Objects 1.0 nas seguintes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 1.5 nas seguintes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.0 nas seguintes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.1 nas seguintes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.5 nas seguintes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.6 nas seguintes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Data Access Components 2.7
Palavras-chave: 
kbmt kbcode kbdatabase kbinfo kbusage KB169496 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 169496

Submeter comentários

 

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