导入类型库注意先后顺序

类别:VC语言 点击:0 评论:0 推荐:

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

 

 

 

本文地址:http://com.8s8s.com/it/it413.htm