原来显式调用DLL里的函数会出错的?今晚我的程序突然间出了几次故障,
程序突然自动关闭,啥都不说一声。
好久以前我被“野指针”害过,就是这个症状,
但是这次我可以肯定没有野指针。
初步判断,可能是调用DLL里的函数时有问题。我在电视台工作,我的工作是写我们台的短信平台,
观众用手机参与电视节目的短信互动,
我的程序是进行短信处理,
程序中集成了移动、联通、小灵通三个平台。以前,我用的是隐式调用,
由于移动、小灵通的DLL中有同名函数,
我不得不写三个程序一起运行,
现在,我改成显式调用DLL,把它们合在一起了,
但是问题就这样出来了。电视里播放到互动环节的时候,
大量的移动、联通、小灵通短信是同时来的。凭一两起事故不能作判断,
但是对多起事故分析,我发现每次问题都出在发送移动短信的时候,
于是我对程序作了如下改动:
在原来的基础上加了个try-catch,增加了返回值1
代码如下:typedef int (WINAPI* pSubmitMobile)(...)//...里我省去了参数,因为太长
pSubmitMobile submitmobile;
submitmobile = (pSubmitMobile)GetProcAddress(hDLL_Mobile, "CMPP3Submit");
if (submitmobile == NULL)
{
  return 3;//返回3表示加载函数失败,从来没有返回过
}try//增加了try
{
  submitmobile(...);//...里我省去了参数,因为太长
}
catch(...)//增加了catch和返回值1
{
  return 1;//返回1表示调用函数失败
}
return 0;//反回0表示正常果然,改动过的程序运行不久就抓住一起事故,
果然返回了1,
日志记录了这次事故:
2006-03-30 23:34:54 发送下行调用DLL函数失败!136****7054, 2118这个问题有一定的随机性,
并不是发每条短信都出错,只有极少数,
也不是短信密集的时候才出错,很随机的。
而且更气人的是,
昨天一天没有出现一起这样的事故,
今天却集中出了十几起。
你们写程序时有没有碰到过这样的问题?

解决方案 »

  1.   

    我曾经遇见过这类问题。你检查一下dll的编译链接方式与exe是否相同。
    是程序运行调用dll里的函数释放主程序中的内存时出现的,我的程序是一个服务,是在后台不断的运行,但偶尔会出错,然后就悄无声息的没了。
    最后发现并不是程序有问题,而是主程序和dll得链接方式不同,一个用了静态库,一个使用了动态库。其实程序每次运行到这里都有问题,我在用内存泄漏检测工具时,一旦调用这个函数工具就提示异常出现;但是我使用__try{}语句包含这段代码的时候却检测不到异常,但是当运行一段时间之后会捕捉到内存失败的异常。
      

  2.   

    我这个DLL原来是为静态而设计的,我把它改成了动态,
    于是出现了这样的问题,
    我的程序一天要处理千百条短信,出错机率约为百分之一,
    而且,即使是同一手机发同一短信,也不会都出错,
    所以,出错完全是随机的,这就使得我无法停下来调试。
      

  3.   

    1)做一个测试程序狂调出错的函数。可以判断dll本身是否有问题。
    2)记录所有出错的参数,有可能特定参数才错。比如长度太大
      

  4.   

    谢谢楼上pkrobbie(pkrobbie)的提醒,
    我就是这样做的,
    我的程序有很完善的日志记录,
    因为我写的是服务器程序,没有人会盯着服务器看,
    所以,任何情况都不用对话框、消息框的方式提醒,
    而是一律写日志,
    包括这次的事故,我写了这样一条日志:
    2006-03-30 23:34:54 发送下行调用DLL函数失败!136****7054, 2118
    至于这条短信的详细内容,在另一个日志文件中有完整的记录。
    目前可以说的是,错误完全是随机的,
    楼上说的“长度太大”之类的情况不可能出现,
    因为问题出在下发短信的时候,而不是接收短信的时候,
    下发短信时,数据包中的任何一个内容都是我严格填写的,
    而且,同样的短信内容发送两次根本就不出问题。另外楼上说写一个测试程序,这个是不可行的,
    因为这是跟移动公司的网关实际连接,
    这样测试,会向移动公司提交过多的数据,相当于私自群发。
    移动公司不会同意我这么做。昨晚我把程序作了改动后,
    今开晚上在短信最密集的时段(电视里播出互动内容的时候),
    我盯着它看了看,
    一个小时过去了,成功地记录了两次这样的事故,
    已经没有突然退出的问题了。
      

  5.   

    调用约定的问题,改成
    typedef int CALLBACK (WINAPI* pSubmitMobile)(...)
      

  6.   

    typedef int (WINAPI* pSubmitMobile)(...)改为
    typedef int CALLBACK (WINAPI* pSubmitMobile)(...)?CALLBACK 跟WINAPI本来就是一回事,
    都是__stdcall#define CALLBACK    __stdcall
    #define WINAPI      __stdcall
      

  7.   

    我认为是你的库改动态改的不彻底。我已经提到过,其实异常每次发生,只不过try在release的时候捕捉不到这个异常。强烈建议你检查是否有dll分配的内存exe释放,或者exe分配内存dll释放的情况,如果有的话,我确定就是链接版本的问题。
      

  8.   

    移动短信以前用隐式调用没出过问题吗?
    既然是发送出问题,你还是可以写测试程序的,自己写一个SOCKET服务器程序模拟短信网关,只要接收数据就可以了,不需要处理。然后写测试代码狂发短信就能测试。
      

  9.   

    显式调用DLL里的函数会出错
    不应该,函数名(C和C++区别),调用约定问题,还有就是内存问题,原则上都是认为因素