匯入型別庫注意先後順序
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.其實我應該在錯誤資訊中發現並推測問題的起因的,注意第二行"缺少儲存類或型別說明符",我應該在這兒就意識到是型別沒定義,但是我馬虎了.
的確,查錯也是一種進步^^,至少鍛鍊毅力
-----------------------------------------------------------------------------------------------------------------------------
vigor
2004.12.5