其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

Visual C++ 2005中混合代码的初始化


发布日期:2018年10月17日
 
Visual C++ 2005中混合代码的初始化

在 Visual Studio NET 中初始化混合DLLs很麻烦需要手工干预但在 Visual Studio Visual C++ 和 CLR 团队设计了一种新的初始化模型这种新模型更简单更自动化

Visual Studio NET 的根本问题在于将本地代码和托管代码一起置于单DllMain 期间该池的运行是不安全的托管代码根本就不能在这里运行

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

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

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

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

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

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

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

上一篇:C++BUILDER非可视组件的消息处理

下一篇:把其他C/C++编译器集成到VC2005中