導入類型庫注意先後順序

COM組件通用ADO訪問數據庫,VC中使用組件,導入組件的類型庫是報錯
------------------------------------------------------------------
可能這個問題對別人來說真的不是什麼問題,但是要是遇上了,會被煩死掉的,所以我還是寫出來,希望別人遇上的

時候能得到幫助:
I.問題概述:
        我是在做一個組件的時候,用到了ADO(msado15.dll),按照常規的方法,訪問數據庫(SQL2000).
<1>組件方:
    方法定義:
    HRESULT GetRecordset([in]BSTR queryCmd,[out,retval]_Recordset **RecordsetPtr);
    實現:
    STDMETHODIMP CQueryRec::GetRecordset(BSTR queryCmd,_Recordset **RecordsetPtr)
   {
    AFX_MANAGE_STATE(AfxGetStaticModuleState())

  CoInitialize(NULL);

 _ConnectionPtr   pCon(__uuidof(Connection));
 _CommandPtr    pCmd(__uuidof(Command));
 _RecordsetPtr    pSet(__uuidof(Recordset));

 pCon->Open(_T("Provider=SQLOLEDB.1;Data source=127.0.0.1;Initial Catalog=Northwind"),
                   _T("sa"),_T(""),adOpenUnspecified);
 pCmd->ActiveConnection=pCon;
 CString command(queryCmd);
 pCmd->CommandText=command.operator LPCTSTR();
 pSet->PutRefSource(pCmd);
        pSet->CursorLocation=adUseClient;
 _variant_t vNull(DISP_E_PARAMNOTFOUND,VT_ERROR);
 pSet->Open(vNull,vNull,adOpenDynamic,adLockOptimistic,adCmdText);
        pSet->QueryInterface(__uuidof(_Recordset),(void**)RecordsetPtr);

 CoUninitialize();
 return S_OK;
}
<2>vc客戶端:
    1.在vc客戶端使用組件都先要導入組件的類型庫,所以我也按常規的導入了類型庫
      #import "GetRec.tlb"
      using namespace GETRECLib;
    2.然後我也想到了,組件返回的類型裏有_RecordsetPtr類型的智能指針,我於是有導入了msado15.dll
      #import "msado15.dll" no_namespace rename("EOF","EndOfFile")

II.錯誤信息:
   做完上面之後,我加入了使用組件的方法,萬事大吉,開工了,開始編譯,錯誤如下:
    ...: error C2146: 語法錯誤 : 缺少“;”(在標識符“GetRecordset”的前面)
    ...: error C2501: “GETRECLib::IQueryRec::_RecordsetPtr” : 缺少存儲類或類型說明符
    ...: warning C4183: “GetRecordset”: 缺少返回類型;假定爲返回“int”的成員函數
    ...: error C2143: 語法錯誤 : 缺少“;”(在“GETRECLib::IQueryRec::GetRecordset”的前面)
    ...: error C2433: “_RecordsetPtr” : 不允許在數據聲明中使用“inline”
    ...: error C2501: “_RecordsetPtr” : 缺少存儲類或類型說明符
    ...: error C2064: 項不會計算爲接受 2 個參數的函數
我檢查了很多遍,都沒其他的問題,怎麼問題老是這樣呢,鬱悶哦,主要是這問題的錯誤不好查,提示就是缺";"什麼的,就是語法錯誤,可是沒語法錯誤,我這點還是肯定的,因爲我就只在一個新的工程裏寫上#import "GetRec.tlb"就錯了,更讓我迷惑的是用VB調用這組件沒問題,正常,這下我可真不知道怎麼好,因爲這問題不想其他的,我還可以憑平時的一點點經驗查錯,這我確實沒法了,我也開始以爲是VC的一個bug.

IIV.問題解決:
    過了三四天了,我沒事就拿這代碼來琢磨琢磨,終於在無意中發現是自己犯了個不注意的錯誤,“導入庫的順序”
    我在vc客戶端的StdAfx.h中:
    1.#import "GetRec.tlb"
    2.#import "msado15.dll" no_namespace rename("EOF","EndOfFile")
    vc編譯器生成的"GetRec.tlh",也就是組件的頭文件,裏面就有_RecordsetPtr,但是在這個VC客戶端裏面不能識別這種類型,的確,我是在第二步導入了"msado15.dll"但是,在這之前,頭文件的定義裏卻不能識別,編譯器對一個文件的編譯都上自頂向下的,所以不認識_RecordsetPtr,於是我換了導入的先後順序,Ok,no problem!

IV.經驗教訓:
   1.編譯器對源文件的編譯都有自頂向下的先後順序,定義要放前面,也就是想上面那種問題,要先定義類型,才能識別使用。
   2.其實我應該在錯誤信息中發現並推測問題的起因的,注意第二行"缺少存儲類或類型說明符",我應該在這兒就意識到是類型沒定義,但是我馬虎了.

的確,查錯也是一種進步^^,至少鍛鍊毅力shades_smile.gif

-----------------------------------------------------------------------------------------------------------------------------
                                                                                                      
                                                                                                                                                                 vigor

                                                                                                                                                               2004.12.5

 

 

 

發佈了28 篇原創文章 · 獲贊 0 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章