So Crazy STL is!

lbqsv 2003-05-29 10:34:02
two dll can't exchaned a set refrence!

assume dll2 depened on dll1,and some function f(set<DWORD> &setRef) in dll1 will be called in dll2
code example:

dll2:
.....
set<DWORD> setTemp;
f(setTemp);
....

dll1:

....
void f(const set<DWORD> &setRef)
{
...
int nCount = setRef.count(1); //----------------this line will //cause access violiation exception! //break in some STL code!
...
}

i don't know why,can you give me an answer!

THANKS!
...全文
12 点赞 收藏 26
写回复
26 条回复
Gary-Kung 2010年06月04日
mark一下,得看看
回复 点赞
lbqsv 2003年08月29日
这个问题早已经解决了,不过还是谢谢各位的参与。
plainsong(短歌) 先生说的很有见地!
回复 点赞
代码之诗 2003年08月09日
flybusflybus(风) :

我的 DLL 是在 VC 中写的,应用程序也是在 VC 中,使用的是完全一样的 STL!它照样出错。
同样的代码,DLL 和 应用程序均在 CB 下编译,则完全没有问题。所以,什么 STL 库不配套是不对的,如果不一样的库当然不行,这我知道。可能是我没说清楚?

至于 HeapCreate ,我已经说了,我没有用它至于操作系统会不会悄悄的用它,我想,CB写的程序也在此操作系统下运行,可见操作系统也没有用它,那么,除了 STL ,我还能怀疑谁?请指教。

最后,如果你说在 DLL 中用了 STL 却在 VC 下没出问题,那么请注意我说的很清楚的细节:什么时候会出,什么时候不会出。如果仅在 DLL 内部使用,当然不会出问题,甚至和应用程序的 STL 版本不同都没关系。
回复 点赞
flybusflybus 2003年08月08日
每个动态库有个堆栈并没有什么不可思议,如果你喜欢你自己也可以HeapCreate
不过sdk文挡没错,的确动态库和程序通常是用一个堆栈
至于错误的原因不要和stl或者别的什么拉在一起混淆视听,错误的原因是库不配套,就象你new出来的东东然后去free一样,根本就是2套东西,而拉上stl容易出错的原因只是因为stl运用伴随着诸多的内存分配与释放而已,所以动态库里用stl用好了你放心就是了,公司里项目里的程序用标准c++写的,unix、windows下都跑,stl到处用,动态库也有好几十个,一切ok
回复 点赞
代码之诗 2003年08月07日
顺便再说一句,我在 VC 中把所有的链接方式都试过了一遍,并不象 IT_WORKER 说的那样就行了,它一样出错。
回复 点赞
代码之诗 2003年08月07日
这个问题我也遇到过。我是在 DLL 介面中传递了一个 vector,由 DLL(Explicit Load 的) 填充之,而由应用程序使用。从观察来看,错误发生在 vector 析构时,而此时 DLL 已经 FreeLibrary 了。如果交换 vector 析构与 FreeLibrary 的顺序,错误依旧,只是地方不同。
如果在主程序中先行 reserve 分配好空间,则安然无事。
根据这个,我同意 IT_WORKER 的说法。
可是,让我郁闷的是,按 SDK 文档的说法,我生成的仅是一个普通的 DLL,它应该 all of its memory belongs to the application who load it。并且文档中明确批指出:DLL 使用 Application 的栈,而且用的是 Application 的堆!
还要说明的一点是,此问题仅出现在 VC(6 和 7 都出) 中,完全一样的代码,在 CB 中编译后运行完全正常,似乎又在证明着 SDK 的说法。
说 DLL 有自己的堆的说法,我持怀疑态度,这不但是因为 SDK 中的说法,还因为我自己有个想法:如果 DLL 有自己的堆,那么按照 DLL 的运行方式,则每与一个进程 attach ,就必须新获取一个堆…… 这也太不可思议了吧?我从来没在 DllMain 里干过这种事啊?而 Windows 不会瞒着程序员做这么复杂的事吧?
所以,我怀疑应是 VC 所使用的 STL 的内存分配策略与此情况冲突所致,具体如何,则只有看看源代码了。如哪位有闲,不妨试试。
回复 点赞
ckacka 2003年08月03日
to xorong(普渡众生):
“传大量数据用指针”

在rpc的基础上就无效了:)
回复 点赞
短歌如风 2003年08月03日
我曾经使用“纯抽象类”的方法在VC和Delphi编写的DLL间传递对象,没有任何问题。事实上COM就是利用了这种方法来完成“二进制级重用”特性的。不过由于标准中没有规定多态的实现方法,这种方法不能说是很可靠,但在目前所有流行的编译器下还是可以考虑使用的。如果想要更可靠,请使用COM(目前在C++中可以使用“纯抽象类”来定义COM Interface,如果多态实现方法改变,就要改用C方式:使用结构——函数指针表,不过我想开发工具会提供一些封装好的类来处理这个问题,所以相对可靠一些)。
回复 点赞
sam1111 2003年08月01日
有趣
回复 点赞
zh7780 2003年08月01日
有道理!
回复 点赞
疯狂的魔法 2003年08月01日
我得习惯做法是在dll之间,甚至在dll与主程序之间只传简单数据类型
传大量数据用指针,数据的组织参考tcp/ip的协议的数据组织方式的。
所以设计dll接口的时候一定要小心了
因为dll有可能是用不同的编译器写出来,甚至是同一编译器的不同版本写出来的
也不要传对象、结构体、或者是对象结构体的指针等,就算是相同的代码,不同的编译器编译出来的代码在内存上有可能不一样
回复 点赞
tigerfox 2003年08月01日
开眼界!
回复 点赞
短歌如风 2003年07月31日

IT_worker所说使用dynamic CRT library并不能完全解决所有的内存管理问题,只能是对于某一STL实现有效。有些STL实现在allocator中使用了自己的私有内存池,以处理小块内存分配效率问题,而封装这个内存池的对象既不在CRTL中,也不是allocator的成员,而是一个全局变量或静态成员。这是如果你在DLL间传递STL容器引用的话,你仍然要面对不同DLL(EXE)使用不同allocator内存池的问题。
回复 点赞
glasswing 2003年07月31日
看看
回复 点赞
Icat 2003年07月30日
AV错误?!break in some STL code!?
能否将代码发给我
icatme@yeah.net
回复 点赞
hellwolf 2003年07月30日
长见识:

qqchen79(知秋一叶 [MS MVP]):
1. You can't mix different STL implementations (stlport with MSVC).
2. You can't mix different version of STLs (Debug vs Release).

前一阵子,我用vc7作了一个lib,然后测试的时候怎么也不能链接,后来才发现,lib是Release的,而测试程序是Debug的,当时并不知道为什么。看了qqchen79(知秋一叶 [MS MVP])的一席话顿时茅塞顿开
回复 点赞
ckacka 2003年07月30日
这个问题有意思,希望有这方面经验的朋友来看看!
回复 点赞
gridcomputing 2003年07月30日
mark
回复 点赞
IT_worker 2003年07月30日
首先你必须保证qqchen79所说的两条,另外在你的两个dll中的设置必须正确。
在VC6下的project\setting\c++\category\code generation\Use run-time library\
中必须选择Mutithread dll或者Mutithread dll Debug版。
VC缺省的选择是Mutithread也就是静态run-time library这样每一个dll都有一个crt内存的分配堆,两个不同的dll它们crt的内存分配堆不同操作当然回死机。如果改成crt的dll版一切问题就都会解决。
回复 点赞
flybusflybus 2003年07月30日
回复 点赞
发动态
发帖子
工具平台和程序库
创建于2007-09-28

8235

社区成员

2.7w+

社区内容

C/C++ 工具平台和程序库
社区公告
暂无公告