软件架构师何志丹
跨dll操作stl对象时(如:std::string、std::vector)崩溃,原因:在不同堆中申请、释放内存。如果一个dll以stl为主要类库,这种情况必定发生。主要分如下几类:
1,导出函数出参使用了stl对象。
2,导出了类,此类有公有成员。可以通过笨办法解决,不设置公有变量,通过Set和Get函数操作成员,工作量巨大。
1,VC6 Debug测试崩溃的情况。
被调用方(dll) | 调用方(exe) | 是否崩溃 |
MDd | MDd | 正常 |
MD | 正常 | |
MTd | 崩溃 | |
MT | 崩溃 | |
MD | MDd | 正常 |
MD | MD | 正常 |
MD | MTd | 崩溃 |
MD | MT | 崩溃 |
MTd | MTd | 崩溃 |
Mt | 崩溃 | |
MDd | 崩溃 | |
MD | 崩溃 | |
MT | MTd | 崩溃 |
Mt | 崩溃 | |
MDd | 崩溃 | |
MD | 崩溃 |
结论:除了双方都是MD或MDd,必定崩溃。
2,VC6 Release版,不考虑MDd和MTd。
被调用方(dll) | 调用方(exe) | 是否崩溃 |
MD | MD | 正常 |
MT | MD | 正常 |
MD | MT | 正常 |
MT | MT | 正常 |
结论:双方都是Release版,不会崩溃。
3,开发环境VC6,被调用方Release版,调用方Debug版。
这种情况很常见,比如:使用第三方组件,第三方组件往往没Debug版,所以调试时,只能用Release版。
被调用方(dll) | 调用方(exe) | 是否崩溃 |
MD | MTd | 崩溃 |
MDd, | 崩溃 | |
MT | MTd | 崩溃 |
MDd | 崩溃 |
结论:必定崩溃。
4,VC8(VS2005)Debug
被调用方(dll) | 调用方(exe) | 是否崩溃 |
MDd | MDd | 正常 |
MDd | MTd | 崩溃 |
MTd | MTd | 崩溃 |
MTd | MDd | 崩溃 |
5,VC8(VS2005)Release
被调用方(dll) | 调用方(exe) | 是否崩溃 |
MT | MT | 崩溃 |
MT | MD | 崩溃 |
MD | MT | 崩溃 |
MD | MD | 正常 |
6,VC8(VS2005)被调用方Release,调用方Debug。
被调用方(dll) | 调用方(exe) | 是否崩溃 |
MD | MD | 崩溃 |
无需实验 |
终上所述:
Debug版都是MDd,Release版都是MD,才不会崩溃。