怪事!关于动态连接dll
wdh 2000-06-09 06:56:00 在我的程序中使用了MS的rapi.dll,开始我使用的是静态链接的方法,即包括rapi.h和rapi.lib两个文件,这时我的程序一切正常。
后来我改用动态链接的方法,即没有包括rapi.h和rapi.lib两个文件,程序编译通过,但执行时出现运行时错误,而且问题颇怪。
当我运行DEBUG版本时,会出现这样的怪事:
for(i=0;i<CeFieldCount;i++)
{
CeRecordset.GetODBCFieldInfo(i,CeFieldInfo);
pCeProps[i].wLenData = 0; //程序在此处出错
...
}
出错原因是变量i的值变成了一个很大的数,而pCeProps是一个不大于50个元素的数组,CeRecordset是CRecordset类的对象,其成员函数GetODBCFieldInfo的声明为:
void GetODBCFieldInfo(short nIndex,CODBCFIELDINFO& fieldinfo)
我认为,从语法来说,i的值是不可能被CeRecordset.GetODBCFieldInfo(i,CeFieldInfo);这条语句改变的,但是我的程序偏偏就出现了这种情况,真是不可思议。
当我运行release版本时,错误却在另外一处发生:
CString strDBName=CeDB.GetDatabaseName();
CeDB是CDatabase类的对象,程序运行到这里就回执行非法操作,可在我静态链接连接rapi.dll时,这条语句工作得很正常。
现在我把我使用动态链接dll的代码的一部分列举如下,希望大侠们帮忙看看有什么错误。
在rapi.h中的声明为:(rapi.h是MS提供的)
STDAPI_(CEOID) CeCreateDatabase(LPWSTR, DWORD, WORD, SORTORDERSPEC*);
我的程序中的声明为:
typedef CEOID (*_pCeCreateDatabase)(LPWSTR, DWORD, WORD, SORTORDERSPEC*);
_pCeCreateDatabase pCeCreateDatabase ;
得到函数地址:
pCeCreateDatabase=(_pCeCreateDatabase)GetProcAddressEx(m_hRapi,_T("CeCreateDatabase"));
调用函数的代码为:
pCeCreateDatabase(...);
其中GetProcAddressEx()为自定义函数,目的是解决GetProcAddress()不能使用UNICODE字符串的问题。其代码如下:
FARPROC CCeDBConvertDlg::GetProcAddressEx(HMODULE hModule, LPCWSTR lpProcName)
{
int iSize=wcslen(lpProcName);
char* strFuncA=NULL;
FARPROC pRet;
try{
strFuncA=new char[iSize+1];
wcstombs(strFuncA,lpProcName,iSize);
strFuncA[iSize]=0;
pRet=GetProcAddress(hModule,strFuncA);
}
catch(...)
{
delete []strFuncA;
}
delete []strFuncA;
return pRet;
}
还望大侠们多多指点.