调用了一个DLL后,程序运行结束时出错

neversaydie518 2007-11-28 10:26:44
小弟现在封装了一个DLL,然后做了一个测试程序TEST.exe来测试该DLL。该DLL用来使用ADO实现查询数据库的功能,导出查询数据库的函数接口。
EXE程序调用该DLL,测试结果表明查询数据库成功,但是在EXE程序结束的时候出错。跳出出错对话框
说:
"0x00000000"指令引用的"0x00000000"内存。该内存不能为"read"。要终止程序,请单击"确定"。
我点这个"确定"按钮四次后,程序才结束。

我怀疑是DLL里面的内存管理上有问题,但是DLL里面没有使用new或者其他分配内存的语句。

这样会是什么问题呢?如何调试呢?
...全文
153 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangjin1222 2011-06-29
  • 打赏
  • 举报
回复
我也遇到了这种问题。exe运行正常,但是封装成dll调用就出错。郁闷死了。
oo_v_oo 2007-11-30
  • 打赏
  • 举报
回复
LZ还是先加分吧
neversaydie518 2007-11-30
  • 打赏
  • 举报
回复
楼上的这么晚还不睡觉
oo_v_oo 2007-11-29
  • 打赏
  • 举报
回复
LZ的临界区怎么使用的
看上面的程序只有一个地方使用了临界区啊,是不是还有其他地方使用

记住,临界区是系统资源,可以暂停当前线程的进程,如果由于其他地方使用临界区,而且发生暂时堵塞
LZ使用的g_AdoDatabase变量也许已经失效,0000是可能的

LZ可以在上面临界区使用的g_AdoDatabase前,判断其是否有效,或者使用OllyDBG抓一下故障前的IP和堆栈
neversaydie518 2007-11-29
  • 打赏
  • 举报
回复
很奇怪,如果把g_AdoDatabase做为局部变量,则不会出现上面那个错误
大家说说是为什么呢?释放内存的顺序吗?
neversaydie518 2007-11-28
  • 打赏
  • 举报
回复
bool InitDB()
{
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;
}

主要的代码就是这些
这个论坛怎么在帖子里插入源代码啊,那个图标怎么用啊
neversaydie518 2007-11-28
  • 打赏
  • 举报
回复
Release下也是不行
neversaydie518 2007-11-28
  • 打赏
  • 举报
回复
1.是用C++写的DLL,也是用C++调用
2.Release下只能运行啊
jesse_apple 2007-11-28
  • 打赏
  • 举报
回复
建议你在Release下调试。
vrace 2007-11-28
  • 打赏
  • 举报
回复
你是不是用 c++ 写的 DLL, 用其他语言调用的?

如果是的话,记得在你的导出函数前面加 WINAPI 修饰
shanhqk 2007-11-28
  • 打赏
  • 举报
回复
重新设置下环境,调试Release
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代码。
shanhqk 2007-11-28
  • 打赏
  • 举报
回复
Release的程序是可以调试的,
以前的论坛中有这样一个例子,在release中设置让其可以调试。
同样的也是一个关于DLL的调试例子,和LZ的很像 ,
搜索一下吧,估计可以解决。
neversaydie518 2007-11-28
  • 打赏
  • 举报
回复
如果我把断点设置在那个函数的外面,就出错,说是Unhandled exception
然后光标就移到了
00000000 ???
neversaydie518 2007-11-28
  • 打赏
  • 举报
回复
DLL中的代码放到EXE程序中执行没问题。就是封装成DLL后,出了很多问题。
qcwx828 2007-11-28
  • 打赏
  • 举报
回复
有可能是跟数据库操作相关。。仔细检查一下数据库相关的操作过程
内存泄漏 2007-11-28
  • 打赏
  • 举报
回复
如果还不行,把你DLL中的代码放到一个EXE程序中调试~
内存泄漏 2007-11-28
  • 打赏
  • 举报
回复
把数据库操作的代码用try包起来看看能否捕获到异常??

try
{
...
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧