c++, DLL, std::string, STL, crt
这里有非常详细的一篇讨论仅供参考
也有可能是一个已知的微软实现问题
最近在重构项目时遇到的一个问题:提取了原来项目中的一些公共方法到一个新的DLL,暴露的工具方法中多数以const std::string& 为参数。在调试时
发现当主程序(exe)调用DLL中的这些工具方法时传入的string会发生莫名其妙的变化(不是encoding问题)。比如在主程序中的string的buffer地址为0x0118cd8,可是刚刚进入工具方法(const std::string&)这个string的内容就变了,而且buffer地址也发生了变化,根据观察只有几个字节的偏移。开发环境为VC2008。
排除过程
首先检查了C++的Runtime library,确定都是/MD,另外调整了两个工程的其它编译,连接选项到一致,问题依旧。最后在编译命令行中(Command Line)发现了一个可疑点,_DEBUG预编译项。可是我明明用的是/MD(Multi
threaded DLL),不是/MDd(
debug),为什么会有_DEBUG呢?为了验证猜测,使用“Undefine Preprocessor Definitions”取消了_DEBUG定义,问题解决!
其实问题的根源在于我这个调试用的Build Configuration,是基于默认的Debug创建的,这样,VS或默认为你加上_DEBUG定义,而我们这个项目原来的工程的debug环境都是基于Release配置创建的build configuration。其实不仅是string,STL中的很多类型(不敢说全部)都存在这样的问题。
总结
1. 为了保证程序行为的一致性,DLL与主程序的runtime library最好完全一致,否则便可能引入各种链接和运行时
错误。
2. DLL的
接口方法好暴露C式的方法签名,这样一方面可以提高LIB的可用性,还能杜绝STL对象的这种问题。
3. 错误的排除可以从编译器和链接器的的
command line参数入手
4. 在为项目添加新的工程时尤其需要注意