รายละเอียด: การใช้ ActiveX Data Objects (ADO) ผ่านทาง #import ใน VC ++

การแปลบทความ การแปลบทความ
หมายเลขบทความ (Article ID): 169496 - ผลิตภัณฑ์ที่เกี่ยวข้องในบทความนี้
ขยายทั้งหมด | ยุบทั้งหมด

เนื้อหาบนหน้านี้

สรุป

ไดเรกทีฟ #import ใน c ++ Visual เสนอกลไกใหม่ที่มีประสิทธิภาพสำหรับ จัดการกับเซิร์ฟเวอร์ OLE เมื่อใช้กับ ActiveX Data Objects (ADO), #import สามารถทำให้การเรียกดูที่ข้อมูลของคุณ บทความนี้กล่าวถึงคืออะไร จำเป็นต้องใช้ประโยชน์จาก #import กับ ADO

ข้อมูลเพิ่มเติม

ก่อนที่คุณสร้างอินสแตนซ์ของใด ๆ คลาสที่สร้างโดย #import

การเตรียมใช้งาน OLE ได้ก่อนที่จะสร้างอินสแตนซ์ใด ๆ ของคลาสที่เป็นสำคัญ สร้าง โดย #import ตัวอย่างเช่น รหัสต่อไปนี้มีความปลอดภัย ได้ประกาศตัวชี้สมาร์ท #import สร้าง OLE แล้ว instantiates สมาร์ท ตัวชี้:

   // Declare smart pointer of Recordset
    _RecordsetPtr     p;

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

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

      ...
   }
				
โค้ดตัวอย่างถัดไป อย่างไรก็ตาม ไม่ปลอดภัย และสร้างภาพไม่สามารถจัดการได้ ข้อยกเว้น ชี้สมาร์ทสากล p คือทั้งประกาศ และอินสแตนท์ (โดย virtue ของส่ง 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 struct ไม่ประกาศ และอินสแตนท์ก่อน p และ ดังนั้น initializes OLE ในตัวสร้างของมัน ไม่ มีชนิดนี้ของ fail-safe คุณจะเห็นข้อความแสดงข้อผิดพลาดต่อไปนี้:
ข้อยกเว้นที่ไม่สามารถจัดการได้ใน [โปรแกรม] (KERNEL32DLL): 0XE06D7363
ข้อยกเว้น c ++ Microsoft

การใช้งาน #import ที่ถูกต้อง

จำเป็นต้องเรียกใช้ ADO อย่างถูกต้องในโปรแกรมของคุณ หรือคุณสามารถมี ข้อผิดพลาดของคอมไพเลอร์ รหัสต่อไปนี้อธิบายเกี่ยวกับวิธีการใช้ #import กับ Msado10.dll MSADO15.dll ถูกต้อง:

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

การจัดการข้อผิดพลาด

ด้วย ADO คุณอาจได้รับข้อผิดพลาดใน HRESULT ส่งคืนมาจากวิธีการของ ADO คุณอาจได้รับข้อยกเว้นที่ยกกำลัง ด้วยคลา #import ที่สร้างขึ้น และสำหรับ เงื่อนไขอย่างใดอย่างหนึ่งคอลเลกชันของข้อผิดพลาด ADO อาจรวบรวม เมื่อต้องการ รับที่เก็บรวบรวมข้อผิดพลาด ที่คุณต้องการให้วัตถุที่ถูกต้องในการเชื่อมต่อ สำหรับข้อมูลเพิ่มเติมโปรดดูบทความในฐานความรู้ของ Microsoft ต่อไปนี้:

169498ข้อมูล: ดึงข้อมูลรายละเอียดข้อผิดพลาดจาก ADO ใน VC ++ ด้วย #import

ADO และ Dbdaoint.h

ความพยายามที่จะรวม ADO (ผ่าน #import) และ MFC DAO หรือ SDK DAO ในแฟ้มเดียวกันกับการใช้งาน เป็นดังนี้:

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

  #import <msado15.dll> no_namespace ...
				

สร้างข้อผิดพลาดที่หกดังต่อไปนี้:

ข้อผิดพลาด C2011: 'EditModeEnum': 'enum' พิมพ์ redefinition
ข้อผิดพลาด C2011: 'LockTypeEnum': 'enum' พิมพ์ redefinition
ข้อผิดพลาด C2011: 'FieldAttributeEnum': 'enum' พิมพ์ redefinition
ข้อผิดพลาด C2011: 'DataTypeEnum': 'enum' พิมพ์ redefinition
ข้อผิดพลาด C2011: 'ParameterDirectionEnum': 'enum' พิมพ์ redefinition
ข้อผิดพลาด C2011: 'RecordStatusEnum': 'enum' พิมพ์ redefinition
ขณะที่มากเกือบเหมือนกันในเนื้อหา ค่าที่แท้จริงในแต่ละ ชนิดที่ระบุที่แตกต่างระหว่างสิ่งที่จำเป็น โดย ADO และสิ่งที่จำเป็น โดย DAO คุณมีหลายตัวเลือกในการแก้ปัญหานี้:

  • แยกต่างหาก ADO และ DAO รหัสลงในแฟ้ม.cpp แยกต่างหาก ทำให้การใช้งาน #import หรือ#รวม <afxdao.h bdao.h="">ในการใช้งานที่แยกต่างหาก แฟ้มเป็นขึ้น</afxdao.h>
  • ปรับเปลี่ยนคำสั่ง #import เพื่อสร้าง namespace ที่หาสิ่งใด สร้างขึ้นสำหรับ ADO ซึ่งหมายความว่า คุณจะมีการอ้างอิง namespace เมื่ออ้างอิงถึงวัตถุ ADO ดังที่แสดงในฟังก์ชันที่สอง ด้านล่างนี้ ก่อนที่แสดงวิธีการใช้ ADO แบบเอกสิทธิ์เฉพาะบุคคลภายในฟังก์ชัน แสดงสองวิธีการผสม และตรง ADO และ DAO วัตถุ นี้คือ ไปได้ โดยการอ้างอิง namespace 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;
          }
    						
Msado105.tlh/Msado15.tli dissecting และใช้--------------------------------------------

#import สร้างแฟ้มสองแฟ้ม Msado105.tlh และ Msado15.tli ออกของ typelib ที่อยู่ภายใน Msado15.dll โครงสร้างของไฟล์.tlh สามารถแตกออกเป็นดังนี้:
  • การอ้างอิงไปข้างหน้าและ Typedefs
  • Typedef ชี้สมาร์ทและการประกาศ
  • รายการไลบรารีชนิด
แต่ละได้อธิบายไว้ในรายละเอียดด้านล่างนี้

การอ้างอิงไปข้างหน้าและ Typedefs

มีสร้างการอ้างอิงไปข้างหน้าและ Typedefs โดยใช้การ struct ไม่ __declspec(uuid("...")) บน GUID สำหรับอินเทอร์เฟซคู่สำหรับ อินเทอร์เฟซ และ CoClass ที่กำหนดไว้ใน 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;
   ...
				
อินเทอร์เฟซทั้งหมดไม่ เช่น การเชื่อมต่อมีการใช้งานหลาย ทั้งนี้ขึ้นอยู่กับ typelib แต่สำหรับ ADO อินเทอร์เฟซส่วนใหญ่มีสองรูปแบบ และไม่ นำมาใช้เป็นอินเทอร์เฟซหรือ coclass

ประกาศ TypeDef ชี้สมาร์ท

สำหรับอินเทอร์เฟซและอินเตอร์เฟสที่สอง ตัวชี้สมาร์ทถูกประกาศ ซึ่ง อย่างมากทำโดยใช้อินเทอร์เฟซ:
   ...
   _COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
   ...
   _COM_SMARTPTR_TYPEDEF(ICADOConnection, __uuidof(ICADOConnection));
   ...
				
หมายเหตุว่า ไม่มีตัวชี้สมาร์ทถูกประกาศสำหรับ coclass เชื่อมต่อ อินเทอร์เฟซ

รายการไลบรารีชนิด

ซึ่งรวมถึงชนิดใด ๆ ที่ระบุที่กำหนดไว้ในการ typelib เช่นเดียวกัน การใช้งานตัวชี้สมาร์ทและสินค้า 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;
      ...
   };
				
ในส่วนรหัสก่อนหน้านี้ ส่วนข้อมูลคุณสมบัติใช้ declspec ไป ประกาศการรับ และวางวิธีสำหรับ ConnectionString วิธีการแรปเปอร์สำหรับ ส่วนแสดงวิธีสร้าง โดย #import ซึ่งตัดวิธีการเหล่านี้ และ ยก _com_error ยกเว้นในกรณีนี้ไม่สำเร็จ ดิบ ส่วนวิธีประกาศเมธอดที่แท้จริงที่เรียกโดย อินเทอร์เฟซ

ในขณะที่คุณไม่สามารถเรียก GetConnectionString หรือ PutConnectionString เป็น จริง ๆ ไม่จำเป็น ตั้งแต่ ConnectionString คือ คุณสมบัติที่คุณต้องการ อ้างอิงจะเป็นดังนี้:

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


จะมีการใช้งานจริงของ GetConnectionString/PutConnectionString พบในแฟ้ม Msado15.tli

เมื่อเวลาการใช้วัตถุการเชื่อมต่อในรหัสของคุณ คุณจะต้องใช้ อินสแตนซ์ของตัวชี้สมาร์ทสำหรับอินเทอร์เฟซที่สองรูปแบบที่กำหนดไว้ใน 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 หลังจากวัตถุดังกล่าว จริง ๆ แล้ว ออก และ decrementing เพียงการอ้างอิงของนับโดยไม่มี จริง ๆ destroying วัตถุ โดยเรียกอย่างชัดเจนปล่อย()--โดยไม่ AddRef() เรียกอย่างชัดเจนมากดุล it--#import gladly พยายามที่จะ ปล่อยวัตถุที่ไม่มีอยู่ การสร้างลักษณะพิเศษด้านที่น่าสนใจ และ ความล้มเหลวของลักษณะการทำงาน

คำแนะนำที่ดีที่สุด คุณไม่ AddRef() ไม่ได้ (หรือน้อยไม่จำเป็นต้อง) ไม่ปล่อยอย่างใดอย่างหนึ่ง

ข้อมูลอ้างอิง

  • Com ภายใน โดย Dale Rogerson ISBN 1-57231-349-8
  • OLE COM วัตถุ Viewer (Oleview.exe) ที่ส่งมาพร้อมกับ c ++เสมือนสำหรับการตรวจสอบเนื้อหาของ typelib
  • ถ้าเอกสารเป็น visual c ++ออนไลน์เอกสาร: ค้นหาใน #import
สำหรับข้อมูลเพิ่มเติม ให้คลิกหมายเลขบทความด้านล่างเพื่อดูบทความในฐานความรู้ของ Microsoft:
182389แฟ้ม: ADO เท่ากับ #import และ Getrows/ที่ คั่นหน้า Adovcbm.exe
184968แฟ้ม: Adovcsp.exe แสดงโดยใช้เก็บกระบวนการของ ADO
186387ตัวอย่าง: Ado2atl.exe กลับอินเทอร์เฟซ ADO จาก COM
181733แฟ้ม: #import Adovcbtd.exe ใช้ UpdateBatch และ CancelBatch
166112PRB: การขัดแย้งกับ EOF เมื่อใช้ #import กับ ADO
168354รายละเอียด: ต้นแบบ OLE และข้อผิดพลาดในการให้บริการ OLEDB จะแสดงผ่าน ADO

คุณสมบัติ

หมายเลขบทความ (Article ID): 169496 - รีวิวครั้งสุดท้าย: 28 มกราคม 2554 - Revision: 5.0
ใช้กับ
  • Microsoft Data Access Components 2.7
Keywords: 
kbcode kbdatabase kbinfo kbusage kbmt KB169496 KbMtth
แปลโดยคอมพิวเตอร์
ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:169496

ให้ข้อเสนอแนะ

 

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