VisualC2005中混合代码的初始化

时间:2007-06-15 来源: 作者: 【字体: 减小 增大收藏 | 投稿
  
在VisualStudio.NET2003中初始化混合DLLs很麻烦,需要手工干预。但在VisualStudio2005中,VisualC和CLR团队设计了一种新的初始化模型,这种新模型更简单,更自动化。

  VisualStudio.NET2003的根本问题在于将本地代码和托管代码一起置于单“池”中。DllMain期间该池的运行是不安全的,托管代码根本就不能在这里运行。

  新的模型将静态初始化汇集在两个单独的池中。一个池负责本地的静态初始化;另一个负责托管代码的初始化。

  第一个池在DllMainCRTStartup期间进行初始化,就像本地代码那样。第二个池的初始化,我们加入了一个新的托管代码初始化阶段。当某个包含托管代码的模块被加载到应用程序域(AppDomain)时,CLR将会在任何托管代码运行之前运行一个特殊的.cctor函数(我们把它叫做“模块构造函数”)。

  托管C运行时(msvcmrt.lib)包含一个模块构造函数,由它负责初始化第二个池。同时它还安装一个应用程序域的unload事件来运行托管静态析构函数和exit函数。

财管家园,fs119.net



  这种新模型意味着到托管代码的迁移或添加托管代码到现有的应用程序将变得更加容易,因为不需要再添加定制的初始化入口点。迁移期间,你可能还会碰到本地代码调用托管代码的情况。你的代码要可靠地启动和关闭,必须解决这个问题才行。否则会出现C运行时库的R6031错误,或者在调试器下运行时出现CLR警告。

  为了在VisualStudio2005Beta2或以后的版本中解决这个问题,使用调试器的调用堆栈(callstack)找到此烦人的函数,并将该函数要么移到某个头文件中,或者本地原文件中,以便将它编译成本地代码。你可能注意到了通过#pragmamanaged解决此类问题的建议。请尽量避免这种做法,用这种方法来解决这个问题非常难以凑效。尤其是在你具备自己的DllMain或RawDllMain时更是如此,此时必须保证将此函数放在本地代码集中。

  如果你采纳了保罗描述的解决方案,从VisualC7.1到8.0的迁移不会有太多麻烦。当你重新编译时,你会看到关于使用_vcclrit.h中函数的不满警告。此时删除对该文件的引用并进行手工初始化即可。为了完全恢复使用CRT,你还应该从编译开关中去掉/Zl,从链接开关中去掉/NOENTRY。
财管家.园.fs119.net


  这是VisualStudio2005中大量改动的地方之一,目的是方便将C应用程序迁移到托管代码使用环境。使用最新的生成产品,我们已经看到大量应用程序在相当短的时间内转移到了托管环境中。VisualStudio2005Beta2出炉后用用看吧,并把使用情况反馈给我们。

财软联.盟.fs119.net


上一篇:体验VisualC.NET2005中的STL
下一篇:VISUALC6.0在MDI主框架窗口中添加位图

精品课程推荐