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

|