您的位置:首页 > 其它

程序同时使用微软的多个C运行库的风险

2008-10-25 16:39 204 查看
同时使用微软的多个C运行库的风险

Microsoft的Visual C++是Windows下使用最广的编译器,历史悠久,目前的最新版本是VC2008。VC有多个版本,每个版本都附带一个C运行库。从VC6开始附带的运行库如下:
VC6 msvcrt.dll
VC7(VC 2002) msvcrt7.dll
VC7.1(VC2003) msvcrt71.dll
VC8(VC2005) msvcrt80.dll
VC9(VC2008) msvcrt90.dll
msvcrt.dll后来由Windows自带,成为了Windows系统的一部分,描述也成了“Windows NT CRT DLL”。

假如一个程序在VC2008下面开发,但是它依赖于某些第三方动态库,这些第三方库由VC6编译,这样程序就会同时依赖于msvcrt.dll和msvcrt90.dll这两个C运行库。这样做有什么风险呢?程序中很多对象、资源都是由C运行库维护的(那些不依赖于C运行库的程序例外),比如内存(通过malloc申请的内存)、文件指针(FILE*)、环境变量。程序依赖多个C运行库,进程中就有C运行库的多个实例,这些个不同C运行库维护的对象、资源是不能混用的,否则就会导致严重的错误。比如通过msvcrt.dll打开的文件指针传递给msvcr90.dll去读取文件内容。
详情可以参考下面的两个文档:
C Run-Time Libraries http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx
Potential Errors Passing CRT Objects Across DLL Boundaries
http://msdn.microsoft.com/en-us/library/ms235460.aspx
这种情况一定会出问题吗?那到不一定。如果动态库的接口设计者注意到了这个问题,接口设计的比较合理,参数和返回值的类型都比较合理,就不会有问题。

另外一种情况与此类似,也会导致多个C运行库实例的出现。那就是:程序中某些库链接到了Debug版本的C运行库,某些库链接到了Release版本的C运行库。

对于新版本的VC来说,如果打了补丁后C运行库进行了更新,新的C运行库和旧的也是不同的版本,即使它们名字相同,它们会被放到/WINDOWS/WinSxS下不同的目录中。这种情况也需要谨慎小心,尽量使用同一个补丁版本进行编译,链接到同样版本的运行库。

在程序有多个库组成时,用同一个编译器编译,同时保证它们的编译选项尽量一致。这样避免一些莫名其妙错误的发生。

同样这个问题在C++运行库中也存在,不再详述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐