[这是TLDR …对不起…]
我在一个巨大的(大多数)C / MFC应用程序上工作,有数百个DLL;它通过COM支持动态加载的“添加”机制,因此可以使用COM互操作在.NET中开发加载项.一些有限的新功能是在.NET中使用这种“插件”机制开发的(尽管仍然是动态加载的);但是,最终用户可以决定不使用此功能.因此,.NET可能无法在启动时加载.
但是,当加载.NET时,我需要进行一些特定于.NET的初始化(特别是设置CurrentUICulture以匹配本机/非托管UI).
一种解决方案就是在代码到处加载新的.NET功能或COM加载项时简单地进行.NET初始化.鉴于此应用程序的性质,它可能是95%的解决方案(大多数用户将使用新功能).
但这不是万无一失的.有人可以通过构建带有/ clr标志的模块随时“随时”添加新的.NET功能(请记住,这是一个巨大的应用程序).
一个更强大(和明显)的解决方案是简单地导致.NET在启动时通过C/C++LI加载.但是,每个字节和时钟周期都很重要的一些顽固的C开发人员并不想这样做;有些可以理解,因为除非/直到加载.NET,否则不需要设置CurrentUICulture.
我想到的另一种可能性是挂钩LoadLibrary并查找mscorlib.现在我知道.NET即将被加载由于某种原因,以正常方式加载它并在其他代码执行任何操作之前进行初始化.但是,挂起LoadLibrary(或其他任何东西)真的不是我想做的事情.
那么,是否有一种简单(更好)/更好的方式来判断是否要加载.NET?
编辑:Reed对LockClrVersion的回答非常接近.唯一的打嗝是,如果你在混合模式DLL /程序集中链接它将无法工作.
// ClrAboutToLoad.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <MscoreE.h> // http://community.bartdesmet.net/blogs/bart/archive/2005/07/22/2882.aspx FLockClrVersionCallback begin_init,end_init; STDAPI hostCallback() { printf("hostCallback()\n"); // we're in control; notify the shim to grant us the exclusive initialization right begin_init(); ICLRRuntimeHost *pHost = NULL; HRESULT hr = CorBindToRuntimeEx(NULL,L"wks",STARTUP_SERVER_GC,CLSID_CLRRuntimeHost,IID_ICLRRuntimeHost,(PVOID*) &pHost); hr = pHost->Start(); // mission completed; tell the shim we're ready end_init(); return S_OK; } int _tmain(int argc,_TCHAR* argv[]) { LockClrVersion(&hostCallback,&begin_init,&end_init); //fnTheDLL(); HMODULE hModule = LoadLibrary(L"TheDLL"); FARPROC fp = GetProcAddress(hModule,"fnTheDLL"); typedef void (*fnTheDLL_t)(); fnTheDLL_t fnTheDLL = reinterpret_cast<fnTheDLL_t>(fp); fnTheDLL(); FreeLibrary(hModule); return 0; }