INFORMACIÓN: Utilizar ActiveX Data Objects (ADO) a través de # import en VC ++

Seleccione idioma Seleccione idioma
Id. de artículo: 169496 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

La directiva # import en Visual C++ ofrece un nuevo mecanismo eficaz para manipular los servidores OLE. Cuando se utiliza con ActiveX Data Objects (ADO), puede simplificar # Import obtener los datos. En este artículo se explica qué es necesario sacar partido de # import con ADO.

Más información

Antes de que crear una instancia de cualquier clases crea # Import

Es importante inicializar OLE antes de crear las instancias de clases creadas por # import. Por ejemplo, el siguiente código es seguro, declara un puntero inteligente # Import, inicializa OLE y, a continuación, crea una instancia del puntero inteligente:

   // Declare smart pointer of Recordset
    _RecordsetPtr     p;

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

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

      ...
   }
				
El siguiente ejemplo de código, sin embargo, no es seguro y genera una excepción no controlada. Del puntero inteligente global p se declara y crea una instancia (en virtud de pasar un uuid específico en el constructor):

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

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

      ...
   }
				
Puesto que p es una variable global, se crea una instancia antes de que nunca se llame a CoInitialize en main(). Puede corregir con el siguiente fragmento de código:
struct InitOle {
      InitOle()  { ::CoInitialize(NULL); }
      ~InitOle() { ::CoUninitialize();   }
    } _init_InitOle_;

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

   ...
				
Una instancia de la estructura InitOle se declara, crea una instancia antes de p y, por lo tanto, inicializa OLE en su constructor. Sin este tipo de prueba de errores, verá el mensaje de error siguientes:
Excepción no controlada en [programa] (Kernel32.dll): 0xE06D7363
Excepción de C++ de Microsoft.

Implementación correcta de # import

Es importante que invocar a ADO correctamente en el programa, o puede tener errores del compilador. El código siguiente muestra la forma correcta de utilizar # import con Msado10.dll el msado15.dll:

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

Control de errores

Con ADO, puede recibir un error en el HRESULT devuelto desde un método de ADO, puede obtener una excepción provocada por las clases de # import genera y para cualquiera de estas condiciones se puede llenar la colección Errors de ADO. Para obtener la colección Errors debe un objeto de conexión válida. Si desea más información, consulte el siguiente artículo de Microsoft Knowledge Base:

169498INFORMACIÓN: Extraer información de errores de ADO en VC ++ con # import

ADO y Dbdaoint.h

Si se intenta mezclar ADO (a través de # import) y DAO de MFC o el SDK de DAO en el mismo archivo de implementación, como sigue:

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

  #import <msado15.dll> no_namespace ...
				

Genera los siguientes seis errores:

Error C2011: 'EditModeEnum': nueva definición del tipo 'enum'
Error C2011: 'LockTypeEnum': nueva definición del tipo 'enum'
Error C2011: 'FieldAttributeEnum': nueva definición del tipo 'enum'
Error C2011: 'DataTypeEnum': nueva definición del tipo 'enum'
Error C2011: 'ParameterDirectionEnum': nueva definición del tipo 'enum'
Error C2011: 'RecordStatusEnum': nueva definición del tipo 'enum'
Mientras muy casi idénticos en el contenido, los valores reales en cada tipo enumerado difieren entre lo que se requiere por ADO y lo necesario DAO. Tiene varias opciones para solucionar este problema:

  • Código de ADO y DAO independiente en archivos .cpp independiente. Mantener el uso de # import o # include <afxdao.h/dbdao.h> en archivos de implementación independiente así.
  • Modificar la instrucción # import para crear un espacio de nombres para nada generado para ADO. Esto significa que tendrá que hacer referencia el espacio de nombres cuando se hace referencia a un objeto de ADO como se muestra en las dos funciones siguientes. El primero muestra cómo utilizar ADO exclusivamente dentro de una función. El segundo muestra cómo los objetos de ADO y DAO de mezcla y coinciden. Esto es posible sólo por referencia explícitamente el espacio de nombres de ADO para cualquier clase de ADO 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 y utilizar--------------------------------------------

# import genera dos archivos, Msado105.tlh y Msado15.tli fuera de la biblioteca de tipos dentro de msado15.dll. La estructura del archivo .tlh se puede dividir como sigue:
  • Reenviar referencias y Typedefs
  • Declaraciones y definiciones de puntero inteligente
  • Elementos de la biblioteca de tipo
Cada uno se describe en detalle a continuación.

Reenviar referencias y Typedefs

Reenviar referencias y las definiciones de tipos se crean mediante el uso de __declspec(uuid("...")) de estructura en el GUID para cualquier interfaz dual, interfaz, y CoClass definida en la biblioteca de tipos.

   ...
   struct __declspec(uuid("00000274-0000-0010-8000-00aa006d2ea4"))
   /* dual interface */ _Connection;
   ...
   struct __declspec(uuid("00000275-0000-0010-8000-00aa006d2ea4"))
   /* interface */ ICADOConnection;
   ...
   struct /* coclass */ Connection;
   ...
				
No todas las interfaces, como la conexión, tienen varias implementaciones. Esto depende de la biblioteca de tipos, pero para ADO la mayoría de las interfaces son dual y no implementada como interfaz o coclase.

Declaraciones de TypeDef de puntero inteligente

Para interfaces duales e interfaces, se declaran punteros inteligentes, que simplifica enormemente mediante la interfaz:
   ...
   _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
   ...
   _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection));
   ...
				
nota que se ha declarado ningún puntero inteligente para la interfaz de conexión de la coclase.

Elementos de la biblioteca de tipo

Esto incluye cualquier tipo enumerado definido en la biblioteca de tipos, como bien implementación de los punteros inteligentes y los elementos de biblioteca de tipos:

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;
      ...
   };
				
En el fragmento de código anterior, la sección de datos de la propiedad utiliza declspec declarar get y ponga métodos de ConnectionString. La sección de métodos de contenedor proporciona métodos creados mediante # import, que ajustan estos métodos y producen una excepción _com_error si no son correctas. La sección métodos RAW declara el método real que se invoca mediante la interfaz.

Aunque puede llamar a GetConnectionString o PutConnectionString, no es realmente necesario. Dado que ConnectionString es una propiedad puede haría referencia como sigue:

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


La implementación real de GetConnectionString/PutConnectionString puede encontrarse en el archivo Msado15.tli.

Cuando llega el momento de utilizar el objeto de conexión en el código, usaría una instancia de puntero inteligente para la interfaz dual que se define en Msado15.tlh de la siguiente manera:

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


Donde pubs es un origen de datos ODBC.

# import y llamada Release() explícitamente

La ventaja de # import es que ocupa de QueryInterface, AddRef y la versión para automáticamente. Sin embargo, si decide iniciar llamar explícitamente a Release(), puede crear problemas por sí mismo.

Dentro de _com_ptr_t es un m_pInterface variable miembro. Como # Import es un contenedor muy ligero, no distingue con m_pInterface después de que el objeto realmente se publique, frente a disminuir sólo contar su referencia sin realmente destruir el objeto. Llamando explícitamente a Release ()--sin AddRef() llamada muy explícitamente para equilibrar # Import se--gladly intenta liberar un objeto que no existe, crear efectos interesantes y comportamiento de bloqueo.

Mejor consejo, hizo no AddRef() (o al menos no es necesario), no versión bien.

Referencias

  • Inside COM por Dale Rogerson ISBN 1-57231-349-8
  • El OLE COM Visor de objetos (Oleview.exe) que se incluye con Visual C++ para examinar el contenido de una biblioteca de tipos.
  • La documentación en pantalla de Visual C++: búsqueda de # import
Para obtener información adicional, haga clic en los números de artículo correspondientes para verlos en Microsoft Knowledge Base:
182389FILE: Adovcbm.exe ADO 1.5 con # import y Getrows y marcadores
184968FILE: Adovcsp.exe demuestra cómo utilizar procedimientos con ADO almacenados
186387EJEMPLO: Ado2atl.exe devuelve interfaces de ADO desde COM
181733FILE: Adovcbtd.exe # import con UpdateBatch y CancelBatch
166112PRB: Conflicto con EOF al utilizar # import con ADO
168354INFORMACIÓN: OLE subyacente y errores del proveedor OLEDB están expuestos mediante ADO

Propiedades

Id. de artículo: 169496 - Última revisión: miércoles, 02 de marzo de 2005 - Versión: 3.2
La información de este artículo se refiere a:
  • Microsoft ActiveX Data Objects 1.0 sobre las siguientes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional
    • Microsoft Visual C++ 6.0 Professional
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 1.5 sobre las siguientes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional
    • Microsoft Visual C++ 6.0 Professional
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.0 sobre las siguientes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional
    • Microsoft Visual C++ 6.0 Professional
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.1 sobre las siguientes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional
    • Microsoft Visual C++ 6.0 Professional
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.5 sobre las siguientes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional
    • Microsoft Visual C++ 6.0 Professional
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.6 sobre las siguientes plataformas
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional
    • Microsoft Visual C++ 6.0 Professional
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Data Access Components 2.7
Palabras clave: 
kbmt kbcode kbdatabase kbinfo kbusage KB169496 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 169496

Enviar comentarios

 

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