关于CList对象在DLL中的使用问题

来源:互联网 发布:java super 编辑:程序博客网 时间:2024/05/22 09:36
问题起源:
  现有一程序和一相关动态库。
   Typedef CList<CRect,CRect&>  LISTRECT;
主程序A:
 A()
{
 ----------------  
LISTRECT clist;
 BF(&clist);  
clist.RemovAll();
--------------------
}
动态库B.dll
在B中定义了函数BF: __declspec(dllexport) void BF(LISTRECT*); 其操作为向链表中加入5个矩形框。
  
运行结果:
当主程序执行到clist.RemovAll()时,崩溃,提示 User breakpoint called from code at Ox------;  
仔细检查,dll应该没有问题,主程序也找不到问题。后考虑到是不是CList对象要先初始化一下,于是,更改主程序如下:
A()
{ ----------------
 LISTRECT clist;  
clist.AddTail(CRect(0,0,0,0));   // new insert  
BF(&clist);  
clist.RemovAll();
-------------------- }
结果,编译通过啦,程序能够得到正确结果。但问题究竟在什么地方?
在随后的尝试中,我发现,在Dll中向链表加入超过10个矩形框时,同样的错误在clist执行RemoveAll时出现了。
查找msdn,发现Clist具有如下使用特点:
声明CList对象时并未开辟空间,即使使用new也一样,只有在加入第一个节点时,才开辟指定大小的空间,其后加入节点就放入这段空间内,当这段空间用完时,系统再次申请同样大小的一段空间。该段空间大小可由CList的构造函数控制,默认值为10,即10个节点。考虑到这个问题,可以确定程序的问题在clist对象在dll中开辟的空间在主程序中释放出现问题。因此,临时想到一个笨方法,即将clist对象初始化时设定一个指定的递增节点数N,然后在主程序中首先加入一个,这样当dll中加入的节点数不大于N-1时,程序都不会存在问题。
 可现在的问题是: 不确定dll中加入的节点个数怎么办?为什么clist对象在dll开辟的空间在主程序中不能控制?      查看了一下msdn中关于 __declspec(dllimport) and __declspec(dllexport),其中有关于dll中数据传出的问题,但尝试了一下,未能得到结果。有明白这里的朋友可以给大家讲解一下。   
 既然是dll问题,如果做成静态的,那肯定是不会有这个问题,试验结果也证明这是可行的。可问题在于,这里不让使用静态库,因为不利于和其他项目挂接。因此问题变成必须使用动态库,在动态库中开辟空间,然后还要安全释放空间。
后来朋友的一句话提醒了我:空间在哪里开辟的就到哪里去释放,因此我定义了一个接口函数: __declspec(dllexport) void freeListU(LISTRECT*) 在里面对list进行了释放,结果显示:
完全正确!
原创粉丝点击