在DLL与EXE之间传递STL容器对象的问题总结

exemple1   
DLL: 
insert(vector <string> *   pvstr) 

vstr-> push_back( "111 "); 

  
EXE: 

vector <string>   vstr; 
insert(&vstr); 
}//ERROR1 
  
解释: 
EXE和DLL都有自己堆,所以在DLL里动态创建的东西,不能在调用DLL的进程里销毁,反之亦然。 
上面的insert()在DLL堆里创建了string对象,而销毁这个对象的动作发生在EXE进程里,即vstr的析构。 
  
exemple2 
DLL: 
foo1(vector <string>   vstr) 

return; 

  
vector <string> foo2() 

vector <string>   vstring; 
return   vstring; 

  
EXE: 

vector <string>   vstring; 
foo1(vstring);//ERROR2 
vstring=foo2(); 
  
}//ERROR3 
  
错误的根本原因与exemple1相同, 
ERROR2是因为vstring在EXE进程空间产生了一个vstring临时的副本vstr。这个副本引用了EXE空间分配的内存块, 
但vstr却属于DLL里的foo1()的局部变量。当foo1()退出时,vstr析构。vstr在试图释放先前的内存块时,发生异常。 
ERROR3和ERROR2类似,只不过这次临时变量实在DLL中产生而在EXE中销毁。 
  
基于以上两点,DLL和EXE之间不能对有引用动态内存块成员变量的对象进行值传递,只能传指针或引用。
而且对传过来的对象不能进行可导致内存释放或重新分配的修改。
  
但下面这个例子,虽然是传指针并且是只读访问,但也有错误。 
  
exemple3 
  
DLL: 
map <int,int> *   getData(){ 
map <int,int> *   pm=new   map <int,int> (); 
pm-> insert(pair <string,string> (1,1)); 
return   pm; 

  
EXE: 
map <int,int> *   pm=getData(); 
map <int,int>   m   =*pm;//ERROR4 
map <int,int> ::iterator   iter=pm-> begin(); 
while(iter   !=   pm-> end()) 

        cout   < <   (*iter).first   ;   //OK,output   "1 " 
        iter++;//ERROR5 

  
上面的错误在与STL的实现有关,我采用的是VC带的STL。里面的关联容器都使用一个叫_Tree的类,_Tree的空节点指针被定义一个 
静态的成员函数: 
xtree:424                 static   _Nodeptr   _Nil; 
_Nil被当成关联容器的最后一个节点。但由于_Nil是静态的,所以一个进程空间只有一个_Nil节点。而DLL和EXE中的_Nil节点是不一样的。 
当在EXE中遍历DLL创建的map对象时,会把DLL中的_Nil节点和EXE中的_Nil节点以确定是否到达最后一个节点。它们永远不会相等,也就找不到终止节点直到访问到非法地址空间而出错。 
  
也就是说,动态连接库和调用动态连接库的进程之间,不能互访STL关联容器对象。同理不同进程之间也不能。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值