程序同时使用微软的多个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++运行库中也存在,不再详述。
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++运行库中也存在,不再详述。
相关文章推荐
- 命令行和界面程序同时使用
- 使用微软的类型提供程序
- 程序中同时使用DAO和ADO连接数据库
- 关于开机出现“安装程序正在为首次使用计算机做准备”的解决方案及微软OOBE与SYSPREP的实用技巧
- 使用一个程序同时启动多个程序(c#)
- Mouse without Borders是微软的一个软件实验项目,这款软件可让鼠标自由在局域网中的多台电脑间移动,键盘输入实现无缝切换,还可以直接用鼠标相互拖拽文件。 如果经常需要同时使用两台以
- 使用微软的安装程序
- 使用一个程序同时启动多个程序(c#)
- 使用unity3D开发同时打开手机前后摄像头实例程序
- 使用微软asp.net语言开发wap网站程序和大部分手机更具兼容性
- 使用Visual Studio的RPC调试功能同时调试COM程序的客户端和服务端
- 【记录】解决VS2015调试Xamarin程序一闪而过(使用微软ANDROID模拟器)
- 使用一个程序同时启动多个程序(c#)
- 编写一个聊天程序:有接收数据部分,和发数据的部分, 这两部分需要同时执行,使用多线程实现,一个控制接收,一个控制发送
- 第四题:对3中的程序进一步改进,要求使用数组来存储这些学生的学号,同时要求学号不能重复(班主任)
- VS2015使用小技巧 同时调试两个控制台程序
- 解决使用微软模拟器VS Emulator for Android在VS2017 Xamarin开发中不能调试程序的问题。
- 使用VC2005/2008/2010编写的程用程序 部署时不需要安装运行库的方法
- 使用Windows Mobile Test Framework进行Windows Mobile程序的自动化测试 - (1)微软Windows Mobile Test Framework简介
- 您可能无法使用服务器管理器,如果两个线程同时访问 IIS 管理 IIS 的修补程序