advantages and disadvantages of delay load (LoadLibrary)
Some knowledgeable people posted the following wisdom about delay load. Archived here to share.
The advantages are that dlls get loaded only when they are used, and you can “statically” bind to an import that may not exist at runtime, and as long as you are careful not to call it, the program will still work downlevel.
The disadvantage is:
1) Some DLLs don’t work DelayLoaded (as mentioned in the limitations of LoadLibrary). In particular, any dll that uses __declspec(thread), or any dll that you want to import data from.
2) You can’t call any API that might be delay loaded in your DllMain (since you can’t call LoadLibrary during DllMain). Probably not a big deal since you’re generally not supposed to call any APIs in DllMain.
3) The DLLs in your process are now initialized in random order. There may be some orders that cause bizarre bugs.
4) In particular, if you “statically” bind to a dll, then your dll is uninitialized before that other dll. If you delayload, then you will be uninitialized after your delayloaded dlls.
5) Since DLLs may be loaded “late”, their preferred base address may be used already by stack or heap data, resulting in a rebasing performance penalty that wouldn’t happen if the Dll was loaded at boot.
6) If the LoadLibrary fails for some reason (at the delay loading site), then your program just crashes. You can catch this exception, but it is difficult to recover from and definitely the API callsite that was expecting to make a call into this delayed dll will have no direct way of detecting failures.
The last one is the biggest burden. It can mean random crashes when your app is under stress (because you’re out of memory to load that DLL). Unless your feature is specifically designed to deal with that DLL not loading (and you’d have to put this code around every place where you call a delayed API), you run this random crash risk.
Delay Loading definitely has its uses and its benefits, but the limitations means it is not correct to blindly delayload everything.
Comments
Anonymous
August 10, 2007
Only 1 is a real disadvantage. 2,3,4,5 in most cases causes no problems. 6 is a real advantage, because instead of receiving error in the loader you can get the error in the runtime and fix it.Anonymous
September 03, 2007
On the contrary, 6 is no advantage at all. A hard program crash is never a good situation to be in if it can be avoided. If you want the same behaviour, then throw your own exception or abort by some other easy to trace & debug mechanism when LoadLibrary fails. At least with that approach you can choose to fail gracefully. 1 is a problem, but if you're doing that sort of thing you probably shouldn't be delay loading anyway. 3/4 is also a big problem when you have an API which then has an API built on top of it, the latter being delay loaded because it may or may not be there.Anonymous
September 07, 2007
In 6 you have the same code for both. LL+GetProcAddress: HMODULE h = LoadLibrary(...); if(!h) throw Exception; W/ DL: CallFunction() // If it fails you get exception Regular call: CallFuUnction() // If it fails in the loader your program cannot run at all !!
- You must not rely on dll load order. It is not good.
- Yes, this can cause problem in some times, I hope it won't cause problems for me :)