INFO: Utilizar ActiveX Data Objects (ADO) através de #import no VC ++

Traduções de Artigos Traduções de Artigos
Artigo: 169496 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

A directiva #import no Visual C++ oferece um novo mecanismo poderoso para manipular servidores OLE. Quando utilizado com o ActiveX Data Objects (ADO), #import pode simplificar a obtenção de dados. Este artigo explica o que é necessário para tirar partido #import com o ADO.

Mais Informação

Antes instanciar criado qualquer classes, #import

É importante inicializar OLE antes de criar quaisquer instâncias de classes criadas pelo #import. Por exemplo, o código seguinte é seguro, tal como declara um ponteiro inteligentes #import, inicializa OLE e instancia, em seguida, 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 ) );

      ...
   }
				
O código de exemplo seguinte, no entanto, não é seguro e gera uma excepção não processada. O ponteiro inteligente global p está declarado e instanciado (devido a passar um uuid específico no construtor):

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

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

      ...
   }
				
Uma vez que p é uma variável global, é instanciado-se antes de CoInitialize nunca é designada por main(). Pode corrigir esta com o seguinte fragmento 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 está declarada instanciado antes p e, deste modo, inicializa OLE no respectivo construtor. Sem este tipo de isento de falhas, verá a seguinte mensagem de erro:
Unhandled excepção no programa de [] (Kernel32.dll): 0xE06D7363
Excepção de Microsoft C++.

Implementação correcta do #import

É importante invocar os ADO correctamente no programa ou pode ter erros do compilador. O seguinte código demonstra a forma correcta para utilizar #import com Msado10.dll o MSADO15.dll:

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

Erro de processamento

Com o ADO, poderá receber um erro de HRESULT devolvido por um método de ADO, poderá receber uma excepção colocada pelos #import gerado classes e para qualquer uma das condições a colecção de erros de ADO pode ser preenchida. Para obter a colecção de erros terá um objecto de ligação válida. Para obter mais informações, consulte o seguinte artigo na base de dados de conhecimento da Microsoft:

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

ADO e Dbdaoint.h

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

  #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' escreva redefinição
Erro C2011: 'LockTypeEnum': 'enum' escreva redefinição
Erro C2011: 'FieldAttributeEnum': 'enum' escreva redefinição
Erro C2011: 'DataTypeEnum': 'enum' escreva redefinição
Erro C2011: 'ParameterDirectionEnum': 'enum' escreva redefinição
Erro C2011: 'RecordStatusEnum': 'enum' escreva redefinição
Enquanto muito quase idênticos no conteúdo, os valores reais em cada tipo enumerado diferem entre o que é necessário pelo ADO e o que é necessário por DAO. Existem várias opções para resolver este problema:

  • Separado código ADO e DAO ficheiros .cpp separado. Manter a utilização de #import ou # include <afxdao.h/dbdao.h> nos ficheiros de implementação separadas bem.
  • Modificar a instrução #import para criar um espaço de nomes para qualquer documento gerado para ADO. Isto significa que terá que referenciar o espaço de nomes quando fizer referência ao objecto ADO como é mostrado nas duas funções. A primeira mostra como utilizar ADO exclusivamente dentro de uma função. Mostra o segundo a mistura e correspondência ADO e DAO objectos. Isto é possível apenas por referência explicitamente o espaço de nomes ADO para qualquer classe de ADO ou 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 utilizar--------------------------------------------

#Import gera dois ficheiros, Msado105.tlh e Msado15.tli do typelib contido Msado15.dll. A estrutura do ficheiro .TLH pode ser interrompida da seguinte forma:
  • Avançar referências e Typedefs
  • TypeDef ponteiro inteligente e declarações
  • Itens de biblioteca de tipo
Cada é descrito detalhadamente abaixo.

Avançar referências e Typedefs

Reencaminhar referências e Typedefs são criados através da utilização de estrutura __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, tal como ligação, tem várias implementações. Isto depende do typelib, mas para o ADO a maior parte das interfaces são duplo e não implementado como interface ou coclass.

Declarações de TypeDef ponteiro inteligentes

Para interfaces e interfaces duplo, ponteiros inteligentes são declarados, que simplifica significativamente utilizando a interface:
   ...
   _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
   ...
   _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection));
   ...
				
nota que foi declarado não ponteiro inteligente para coclass interface de ligação.

Itens de biblioteca de tipo

Isto inclui quaisquer tipos enumerados definidos no typelib, como bem implementação de ponteiros inteligentes os 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;
      ...
   };
				
Fragmento de código anterior, a secção de dados de propriedades utiliza declspec declarar get e colocar métodos para ConnectionString. A secção de métodos de mensagens publicitárias fornece métodos criados pelo #import, moldagem estes métodos e originar uma excepção _com_error se não forem bem sucedidas. A secção de métodos de RAW declara o método real que é invocado pela interface.

Enquanto pode chamar GetConnectionString ou PutConnectionString, não é realmente necessário. Uma vez que ConnectionString é uma propriedade deverá referenciá-lo da seguinte forma:

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


Implementação do GetConnectionString/PutConnectionString real pode ser encontrada no ficheiro Msado15.tli.

Quando for altura para utilizar o objecto de ligação no código, utilizaria uma instância do ponteiro inteligente para a interface dupla definida em Msado15.tlh da seguinte forma:

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


Em que pubs é uma origem de dados ODBC.

#Import e chamar Release() explicitamente

A vantagem de #import é que-encarrega AddRef, QueryInterface e Release para si automaticamente. No entanto, se optar por começar a chamar explicitamente Release(), pode criar problemas para si.

No _com_ptr_t é um m_pInterface variável de membro. Como #import é um wrapper muito fino, torna não distinção com m_pInterface após o objecto, na realidade, COMERCIALIZAÇÃO, versus decrementing apenas a referência contar sem realmente destruir o objecto. Chamando explicitamente Release ()--sem AddRef() muito explicitamente chamada para equilibrar é--#import irá tentar liberar um objeto que não existe, criar efeitos interessantes e comportamento crashing gladly.

Melhor conselho, foi não AddRef() (ou, pelo menos, não é necessário), não liberte-o.

Referências

  • Com interior por Dale Rogerson ISBN 1-57231-349-8
  • O OLE COM objecto Viewer (Oleview.exe) que é fornecido com o Visual C++ para examinar o conteúdo de um typelib.
  • Documentação online do Visual C++: procura na #import
Para obter informações adicionais, clique nos números de artigo existentes abaixo para visualizar os artigos na Microsoft Knowledge Base:
182389FICHEIRO: Adovcbm.exe ADO 1.5 com #import e getrows/marcadores
184968FICHEIRO: Adovcsp.exe demonstra utilizando procedimentos com o ADO armazenados
186387EXEMPLO: Ado2atl.exe devolve ADO interfaces do COM
181733FICHEIRO: Adovcbtd.exe #import utilizar UpdateBatch e CancelBatch
166112PROBLEMA: Conflito com o EOF quando utilizar #import com ADO
168354INFO: OLE subjacente e erros de fornecedor de OLEDB tem exposição através de ADO

Propriedades

Artigo: 169496 - Última revisão: 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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