Information : Utilisation d'ADO (ActiveX Data Objects) via # import dans VC ++

Traductions disponibles Traductions disponibles
Numéro d'article: 169496 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

La directive # import dans Visual C++ offre un nouveau mécanisme puissant pour manipuler les serveurs OLE. Lorsqu'il est utilisé avec ActiveX Data Objects (ADO), # import peut simplifier l'obtention de vos données. Cet article explique ce qui est nécessaire pour tirer parti de # import avec ADO.

Plus d'informations

Avant de vous instanciez un classes créées par # Import

Il est important d'initialiser OLE avant de créer toutes les instances de classes créées par # Import. Par exemple, le code suivant est sûr, car il déclare un pointeur intelligent # import, initialise OLE et instancie ensuite le pointeur intelligent :

   // Declare smart pointer of Recordset
    _RecordsetPtr     p;

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

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

      ...
   }
				
L'exemple de code suivant, toutefois, n'est pas sûr et génère une exception non gérée. Du pointeur intelligent global p est déclaré et instancié (en vertu de l'en passant un uuid spécifique dans le constructeur) :

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

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

      ...
   }
				
Dans la mesure où p est une variable globale, il est instancié avant l'appel de CoInitialize jamais dans main(). Vous pouvez corriger ce problème avec l'extrait de code suivant :
struct InitOle {
      InitOle()  { ::CoInitialize(NULL); }
      ~InitOle() { ::CoUninitialize();   }
    } _init_InitOle_;

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

   ...
				
Une instance du struct InitOle est déclarée et instancié avant p et, par conséquent, initialise OLE dans son constructeur. Sans ce type de sécurité intégrée, vous verrez message d'erreur suivantes :
Exception non gérée dans [programme] (Kernel32.dll): 0xE06D7363
Exception Microsoft C++.

Mise en oeuvre correcte de # import

Il est important d'appeler correctement ADO dans votre programme, ou vous pouvez avoir des erreurs du compilateur. Le code suivant illustre la façon correcte à utiliser # import avec Msado10.dll le msado15.dll :

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

Traitement des erreurs

Avec ADO, vous risquez d'obtenir l'erreur dans HRESULT retourné à partir d'une méthode de ADO, vous obtiendrez une exception levée par les classes de # import généré et pour les deux conditions la Collection Errors ADO peut être remplie. Afin d'obtenir à la Collection Errors, vous avez besoin d'un objet de connexion valide. Pour plus d'informations, veuillez consulter l'article suivant dans la base de connaissances Microsoft :

169498Information : Extraction des informations sur les erreurs à partir de ADO dans VC ++ avec # import

ADO et Dbdaoint.h

Tente de mélanger des ADO (par l'intermédiaire de # import) et DAO de MFC ou le Kit de développement DAO SDK dans le même fichier de mise en oeuvre, comme suit :

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

  #import <msado15.dll> no_namespace ...
				

Génère six erreurs suivantes :

erreur C2011: 'EditModeEnum': redéfinition du type 'enum'
erreur C2011: 'LockTypeEnum': redéfinition du type 'enum'
erreur C2011: 'FieldAttributeEnum': redéfinition du type 'enum'
erreur C2011: 'DataTypeEnum': redéfinition du type 'enum'
erreur C2011: 'ParameterDirectionEnum': redéfinition du type 'enum'
erreur C2011: 'RecordStatusEnum': redéfinition du type 'enum'
Bien que très presque identiques dans le contenu, les valeurs réelles dans chaque type énuméré diffèrent entre ce qui est requis par ADO et ce qui est requis par DAO. Vous disposez de plusieurs options pour contourner ce problème :

  • Code ADO et DAO séparé dans des fichiers .cpp distinct. Conserver l'utilisation de # import ou # include <afxdao.h/dbdao.h> dans également les fichiers de mise en ?uvre distincte.
  • Modifier l'instruction # import pour créer un espace de noms que rien n'est généré pour ADO. Cela signifie que vous a référencer l'espace de noms lorsque vous référencez un objet ADO comme indiqué dans les deux fonctions ci-dessous. Le premier montre comment utiliser ADO exclusivement au sein d'une fonction. Le deuxième montre comment des objets ADO et DAO mélange-correspondance. Cela est possible uniquement en référençant explicitement l'espace de noms ADO pour toute classe de ADO ou d'un type énuméré :

       #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 et en utilisant--------------------------------------------

# import génère deux fichiers, Msado105.tlh et Msado15.tli de la bibliothèque de types contenu dans msado15.dll. La structure du fichier .tlh peut être décomposée comme suit :
  • Références directes et Typedefs
  • Typedef de pointeur intelligent et déclarations
  • Eléments de bibliothèque de type
Chacune est décrite en détail ci-dessous.

Références directes et Typedefs

Références directes et Typedefs sont créés à l'aide de struct __declspec(uuid("...")) sur le GUID pour toute interface double, interface, et CoClass défini dans la bibliothèque de types.

   ...
   struct __declspec(uuid("00000274-0000-0010-8000-00aa006d2ea4"))
   /* dual interface */ _Connection;
   ...
   struct __declspec(uuid("00000275-0000-0010-8000-00aa006d2ea4"))
   /* interface */ ICADOConnection;
   ...
   struct /* coclass */ Connection;
   ...
				
Pas toutes les interfaces, telles que la connexion, ont plusieurs implémentations. Cela dépend de la bibliothèque de types, mais pour ADO la plupart des interfaces sont double et non implémentée comme interface ou de la coclasse.

Déclarations de TypeDef de pointeur intelligent

Pour les interfaces et les interfaces doubles, des pointeurs intelligents sont déclarées, qui simplifie considérablement l'utilisation de l'interface :
   ...
   _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
   ...
   _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection));
   ...
				
Notez qu'aucun pointeur intelligent a été déclarée pour les coclasses interface de connexion.

Eléments de bibliothèque de type

Cela inclut tous les types énumérés définis dans la bibliothèque de types, comme bien de la mise en oeuvre des pointeurs intelligents et éléments de bibliothèque de types :

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;
      ...
   };
				
Dans le fragment de code précédent, la section données de propriété utilise declspec déclarer get et placez les méthodes pour ConnectionString. La section de méthodes wrapper fournit des méthodes créés par # Import, qui encapsuler ces méthodes et déclenchent une exception _com_error s'ils ne sont pas réussies. La section méthodes RAW déclare la méthode réelle qui est appelée par l'interface.

Pendant que vous pouvez appeler GetConnectionString ou PutConnectionString, il n'est pas vraiment nécessaire. Étant donné que ConnectionString est une propriété vous devez le référencer comme suit :

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


La mise en oeuvre effective de GetConnectionString/PutConnectionString vous pouvez trouver dans le fichier Msado15.tli.

Lorsqu'il s'agit de temps pour utiliser l'objet Connection dans votre code, vous utiliserez une instance de pointeur intelligent pour l'interface double, définie dans Msado15.tlh comme suit :

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


Où pubs est une source de données ODBC.

# Import et explicitement appel Release()

L'avantage de # import est qu'il effectue AddRef, QueryInterface et Release pour vous automatiquement. Toutefois, si vous décidez de démarrer explicitement l'appel Release(), vous pouvez créer des problèmes pour vous-même.

Dans _com_ptr_t est un m_pInterface variable membre. # Import étant un wrapper très mince, il ne fait aucune distinction avec m_pInterface après l'objet en fait, plutôt que simplement décrémenter sa référence compter sans détruire en fait l'objet. En appelant explicitement Release ()--sans AddRef() très explicitement appelant afin d'équilibrer il--# Import tentera gladly libérer un objet n'existe pas, création d'effets secondaires intéressants et comportement qui se bloquent.

Best d'avis, vous n'avez pas AddRef() il (ou au moins n'est pas nécessaire de), ne le libère pas soit.

Références

  • Inside COM par ouvrage de Dale Rogerson ISBN 1-57231-349-8
  • L'OLE Explorateur d'objets COM (Oleview.exe) fourni avec Visual C++ pour examiner le contenu d'une typelib.
  • Documentation en ligne de Visual C++: recherche sur # Import
Pour plus d'informations, cliquez sur les numéros ci-dessous pour afficher les articles correspondants dans la base de connaissances Microsoft :
182389FILE : Adovcbm.exe ADO 1.5 avec # import et GetRows/Bookmarks
184968FILE : Adovcsp.exe démontre l'utilisation procédures stockées avec ADO
186387EXEMPLE : Ado2atl.exe renvoie interfaces ADO à partir de COM
181733FILE : Adovcbtd.exe # import Using UpdateBatch et CancelBatch
166112PRB : Conflit avec EOF lors de l'utilisation de # import avec ADO
168354Information : OLE sous-jacentes et les erreurs du fournisseur OLEDB sont exposées par le biais de ADO

Propriétés

Numéro d'article: 169496 - Dernière mise à jour: mercredi 2 mars 2005 - Version: 3.2
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft ActiveX Data Objects 1.0 sur le système suivant
    • Microsoft Visual C++ 4.2 Édition Entreprise
    • Microsoft Visual C++ 5.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 4.2 Édition Professionnelle
    • Microsoft Visual C++ 5.0 Édition Professionnelle
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 1.5 sur le système suivant
    • Microsoft Visual C++ 4.2 Édition Entreprise
    • Microsoft Visual C++ 5.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 4.2 Édition Professionnelle
    • Microsoft Visual C++ 5.0 Édition Professionnelle
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.0 sur le système suivant
    • Microsoft Visual C++ 4.2 Édition Entreprise
    • Microsoft Visual C++ 5.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 4.2 Édition Professionnelle
    • Microsoft Visual C++ 5.0 Édition Professionnelle
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.1 sur le système suivant
    • Microsoft Visual C++ 4.2 Édition Entreprise
    • Microsoft Visual C++ 5.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 4.2 Édition Professionnelle
    • Microsoft Visual C++ 5.0 Édition Professionnelle
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.5 sur le système suivant
    • Microsoft Visual C++ 4.2 Édition Entreprise
    • Microsoft Visual C++ 5.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 4.2 Édition Professionnelle
    • Microsoft Visual C++ 5.0 Édition Professionnelle
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft ActiveX Data Objects 2.6 sur le système suivant
    • Microsoft Visual C++ 4.2 Édition Entreprise
    • Microsoft Visual C++ 5.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 4.2 Édition Professionnelle
    • Microsoft Visual C++ 5.0 Édition Professionnelle
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Data Access Components 2.7
Mots-clés : 
kbmt kbcode kbdatabase kbinfo kbusage KB169496 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 169496
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

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