小弟现在封装了一个DLL,然后做了一个测试程序TEST.exe来测试该DLL。该DLL用来使用ADO实现查询数据库的功能,导出查询数据库的函数接口。
EXE程序调用该DLL,测试结果表明查询数据库成功,但是在EXE程序结束的时候出错。跳出出错对话框
说:
"0x00000000"指令引用的"0x00000000"内存。该内存不能为"read"。要终止程序,请单击"确定"。
我点这个"确定"按钮四次后,程序才结束。 我怀疑是DLL里面的内存管理上有问题,但是DLL里面没有使用new或者其他分配内存的语句。 这样会是什么问题呢?如何调试呢?
EXE程序调用该DLL,测试结果表明查询数据库成功,但是在EXE程序结束的时候出错。跳出出错对话框
说:
"0x00000000"指令引用的"0x00000000"内存。该内存不能为"read"。要终止程序,请单击"确定"。
我点这个"确定"按钮四次后,程序才结束。 我怀疑是DLL里面的内存管理上有问题,但是DLL里面没有使用new或者其他分配内存的语句。 这样会是什么问题呢?如何调试呢?
2.Release下只能运行啊
{
CoInitialize(NULL); InitializeCriticalSection( &g_synDBConnect); if(!ReadConfigInfo())
return false; g_strDBConnect.Format("Provider=SQLOleDB;Data Source=%s;Initial Catalog=%s;User Id=%s;Password=%s",
g_chrDBSrvIP,//数据库服务器所在的IP
g_chrDBName,//访问的数据库的名字
g_chrDBUserName,//访问数据库的用户名
g_chrDBUserPwd//访问数据库的用户密码
);
BOOL bFlag; EnterCriticalSection(&g_synDBConnect);
g_AdoDatabase.Close();
bFlag = g_AdoDatabase.Open(g_strDBConnect);
LeaveCriticalSection(&g_synDBConnect); if(!bFlag)
{
//连接失败
g_bDBNeedReConnect = true;//设置数据库需要重新连接
return false;
} else
{
//连接成功,将重新连接的标志设置为false
g_bDBNeedReConnect = false;
return true;
}
return true;
}void ClearDB()
{
DeleteCriticalSection(&g_synDBConnect); //删除同步对像
CoUninitialize();
}int GetInfo(const char* lpName, int nCount, COMPANY_INFO *lpInfo)
{
if(nCount<0||strlen(lpName)>255||(*lpName==NULL))
return -1; if(!InitDB())
{
ClearDB();
return 0;//初始化数据库连接失败返回0
} CADORecordset Rs; int Tempindex=0;//用于遍历数组的下标 CString strSqlQuery; CString tempstr; double tempbuff = 0.0;//存储临时的数据变量
strSqlQuery.Format(_T("select * from cInfo where name like \'%%%s%%\' "),lpName);
Rs.Open(g_AdoDatabase.GetActiveConnection(),strSqlQuery);
if(nCount==0)
{
if(!Rs.IsEOF())
Rs.MoveFirst(); while(!Rs.IsEOF())
{
nCount++; Rs.MoveNext();
} if(nCount>0)
Rs.MoveFirst(); ClearDB();
return nCount;
} while(!Rs.IsEOF())
{ Rs.GetFieldValue(0,tempstr);
strcpy(lpInfo[Tempindex].ID , tempstr); Rs.GetFieldValue(1,tempstr);
strcpy(lpInfo[Tempindex].name , tempstr); Rs.MoveNext();
if(++Tempindex > nCount)//如果数组缓冲区不够用,返回-6
{
ClearDB();
return -3;
}
}//end while Rs.Close();
if(Tempindex==0)//如果找不到公司名称就返回-7
{
ClearDB();
return -4;
}
ClearDB(); //此时返回的是查询到的公司个数
return Tempindex;
}主要的代码就是这些
这个论坛怎么在帖子里插入源代码啊,那个图标怎么用啊
{
...
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
然后光标就移到了
00000000 ???
处
以前的论坛中有这样一个例子,在release中设置让其可以调试。
同样的也是一个关于DLL的调试例子,和LZ的很像 ,
搜索一下吧,估计可以解决。
1、在Project Settings里选Settings For为All Configurations。
2、在C/C++标签中,Debug info 选 Program Database。
3、在Link 标签中,Category选 Debug,选中Debug info 复选框和Microsoft format。
ASSERT宏在发行版本中不起作用,而应该用VERIFY来进行发行版的调试。如果发行版本运行有问题,可以先禁止所有代码优化再进行调试。 在需要加断点的地方加上:
__asm int 3
不过调试的时候无法显示C程序,只有asm代码。
看上面的程序只有一个地方使用了临界区啊,是不是还有其他地方使用记住,临界区是系统资源,可以暂停当前线程的进程,如果由于其他地方使用临界区,而且发生暂时堵塞
LZ使用的g_AdoDatabase变量也许已经失效,0000是可能的LZ可以在上面临界区使用的g_AdoDatabase前,判断其是否有效,或者使用OllyDBG抓一下故障前的IP和堆栈
大家说说是为什么呢?释放内存的顺序吗?