我通过在C#中编写代码来构建C ++ dll。
我说错了
检测到LoaderLock消息:尝试在OS Loader锁内进行托管执行。不要尝试在DllMain或图像初始化函数中运行托管代码,因为这样做可能导致应用程序挂起。
我尝试搜索该错误的确切含义,但是我写的文章毫无意义,主要是说这只是一个警告,我应该在Visual Studio中将其关闭。其他解决方案似乎是由于iTunes引起的,或者是使用DirectX进行编程时发生的此问题。我的问题与两个都不相关。
谁能解释,这实际上意味着什么?
我通过在C#中编写代码来构建C ++ dll。
我说错了
检测到LoaderLock消息:尝试在OS Loader锁内进行托管执行。不要尝试在DllMain或图像初始化函数中运行托管代码,因为这样做可能导致应用程序挂起。
我尝试搜索该错误的确切含义,但是我写的文章毫无意义,主要是说这只是一个警告,我应该在Visual Studio中将其关闭。其他解决方案似乎是由于iTunes引起的,或者是使用DirectX进行编程时发生的此问题。我的问题与两个都不相关。
谁能解释,这实际上意味着什么?
Answers:
您需要转到菜单Debug-> Exceptions,打开Managed Debugging Assistants,找到LoaderLock并取消选中

Debug->Windows->Exception Settings。其余的与Managed Debugging Assistants \ LoaderLock
加载程序锁的一般概念:系统在DllMain中的锁内运行代码(如-同步锁)。因此,运行里面的DllMain不平凡的代码是“要求死锁”,描述在这里。
问题是,为什么要尝试在DllMain中运行代码?在DllMain的上下文中运行此代码是否至关重要,还是可以生成一个新线程并在其中运行代码,而不必等待代码在DllMain中完成执行?
我认为,托管代码的问题尤其在于,运行托管代码可能涉及加载CLR之类的东西,而且不知道在那里会发生什么情况,从而导致死锁……我不会听从“禁用此警告”的建议。 “如果我是您,因为很有可能您会发现在某些情况下应用程序意外挂起。
这是在.Net 2.0时代提出的一个古老问题,当时对混合模式DLL的支持存在严重的初始化问题,容易出现随机死锁。从.Net 4.0开始,混合模式DLL的初始化已更改。现在有两个单独的初始化阶段:
由于步骤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间接调用其他托管函数,则编译器不会生成任何警告,因此您需要确保该操作永远不会发生,否则您的应用程序可能会随机死锁。
请提醒那些VS2017用户,您需要禁用“ exception helper ”而不是“ exception assistant ”(在VS2017之前),以防止加载程序锁定错误,其设置路径为Debug-> Exception。刚遇到这个问题并浪费了2个小时来寻找解决方案...
我最近在创建用本机代码编写的COM对象的实例时遇到此错误:
m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy"));
这导致了所描述的错误。“检测到LoaderLock”-引发异常。
我通过在额外的线程中创建对象实例来克服了此错误:
ThreadStart threadRef = new ThreadStart(delegate { m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy")); });
Thread myThread = new Thread(threadRef);
myThread.Start();
myThread.Join(); // for synchronization
发生此问题的原因是,Visual Studio中的调试器在一个或多个DLL文件中运行使用Microsoft Foundation Classes 8.0版的托管应用程序的方式。
在以下位置有详尽的阅读:http : //msdn.microsoft.com/zh-cn/library/aa290048(vs.71).aspx