如何:去除对 _vcclrit.h 的依赖性

更新:2007 年 11 月

在 Visual C++ .NET 和 Visual C++ 2003 中,使用 /clr 编译器选项编译的 DLL 在加载时会产生非确定性死锁。通常,此问题称为加载程序锁定问题,并且在 混合程序集的初始化 中进行了详细描述。

为解决此问题,Visual C++ 2003 中提供了 _vcclrit.h,它可以采用避免加载程序锁定的方式帮助初始化 DLL。对于 Visual C++ 2005,初始化按照完全不同的方式进行处理,目的是为了极大程度地降低死锁概率,因此不再需要此头文件。

为了保证向后兼容性,仍然包括 _vcclrit.h,并且使用它的代码继续工作,但是已否决了 _vcclrit.h 的内容。本主题包含移除此头文件中的依赖项所需的建议修改。

说明:

尽管这不是理想的解决方案,但是在包括 _vcclrit.h 之前,可以通过定义 _CRT_VCCLRIT_NO_DEPRECATE 来取消使用 _vcclrit.h 产生的否决警告。

编译器设置更改

下面是从使用推荐的 Visual C++ 2003 加载程序锁定解决方案的项目中移除 _vcclrit.h 时应执行的更改。它们都包含对链接器设置的更改。有关通过 Visual Studio 更改这些设置的说明,请参见 修改项目设置

  • 移除 /NOENTRY 链接器开关。使用 _vcclrit.h 时,需要为该链接器提供 /NOENTRY(无入口点) 开关。不再需要执行此操作了。

  • 请不要将 MSVCRT.LIB 显式输入到链接器中。因为 /NOENTRY 开关是必需的,因此必须显式链接到 CRT 库文件 MSVCRT.LIB。移除 /NOENTRY 后,默认情况下,将在 /clr 编译下链接此库。

  • 从链接器输入中移除 NOCHKCLR.OBJ。不再需要此文件了。

  • 移除强制符号引用。以前,需要使用 /INCLUDE 开关强制以下符号:__DllMainCRTStartup@12、__crt_dll_initialize 和 __crt_dll_terminate。Visual C++ 2005 中不需要这些符号中的任何一个,因此可以安全地将它们移除。

代码更改

除了从代码中移除 #include <_vcclrit.h> 以外,根据代码的性质,可能需要执行某些其他更改。至少,将不再调用 __crt_dll_initialize 和 __crt_dll_terminate,因此可以将它们移除。

请参见

概念

混合(本机和托管)程序集