.NET 4.0和更多最新框架的更新
这是在.Net 2.0时代提出的一个古老问题,当时对混合模式DLL的支持存在严重的初始化问题,容易出现随机死锁。从.Net 4.0开始,混合模式DLL的初始化已更改。现在有两个单独的初始化阶段:
- 在DLL的入口点调用的本机初始化,包括本机C ++运行时设置和DllMain方法的执行。
- 托管初始化,由系统加载程序自动执行。
由于步骤2是在装载机锁之外执行的,因此没有死锁。有关详细信息,请参见“混合装配的初始化”。
为了确保可以从本机可执行文件加载混合模式程序集,您需要检查的唯一事情是将DllMain方法声明为本机代码。#pragma unmanaged
在这里可以提供帮助:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
... // your implementation here
}
同样重要的是,DllMain可能直接或间接调用的任何代码也必须不受管理。限制DllMain使用的功能类型是有意义的,因此您可以跟踪从DllMain可以访问的所有代码,并确保使用编译#pragma unmanaged
。
如果编译器检测到未将DllMain声明为不受管理,则可以通过警告C4747来有所帮助:
1> Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint
但是,如果DllMain间接调用其他托管函数,则编译器不会生成任何警告,因此您需要确保该操作永远不会发生,否则您的应用程序可能会随机死锁。