Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C++
Article

Delay Loading a DLL

Rate me:
Please Sign up or sign in to vote.
4.07/5 (24 votes)
29 May 2006CPOL4 min read 152.5K   1.8K   61   12
Advantages/disadvantages of delay-loading and how to delay-load a DLL.

Introduction

The code snippet shown in this article is used to delay load a DLL, i.e., DLL is implicitly linked but not actually loaded until your code attempts to reference a symbol contained within the DLL. If your application uses several DLLs, its initialization time might be slow because the loader maps all of the required DLLs into the process' address space and there is every possibility that even a single function from one of these DLLs is not called, so a better way for a loading a DLL which is rarely used is to delay load, it i.e., load it when required instead of loading initially. This improves the start up time. Sounds great. Now, we will actually try to delay load a DLL, and analyze its advantages and disadvantages, so all set...

Using the code

First, you create a DLL just as you normally would. You also create an executable as you normally would but you do have to change a couple of linker switches and re-link the executable. Here are the two linker switches you need to add:

/Lib:DelayImp.lib
/DelayLoad:MyDll.dll
#pragma comment(lib, "DelayImp.lib")
#pragma comment(linker, "/DelayLoad:Dll.Dll")
#pragma comment(linker, "/Delay:unload")

So simple, isn't it? Just add the above three lines in your EXE's code and your DLL is delay-loaded. Now, let's have a look at how it is achieved.

The Lib, "DelayImp.lib" switch tells the linker to embed a special function, __delayLoadHelper, into your executable.

The second switch tells the linker the following things:

Remove Dll.dll from the executable module's import section so that the operating system loader does not implicitly load the DLL when the process initializes. You can watch it from the dependency walker utility that ships with VC 6.0. Below is the image of the dependency walker with and without delay loading. As seen, in the case of delay loading, it has no entry in the EXE's dependencies.

As seen in the first case without delay-loading, Dll.Dll is shown in the EXE's dependencies but not in the second image of the EXE which is using delay loaded DLL.

Image 1

Image 2

Continuing abt the linker switch

... It embeds a new Delay Import section (called .didata) in the executable indicating which functions are being imported from Dll.dll.

Resolve calls to the delay-loaded functions by having calls jump to the __delayLoadHelper function.

When the application runs, a call to a delay-loaded function actually calls the __delayLoadHelper function instead. This function references the special Delay Import section and knows to call LoadLibrary followed by GetProcAddress. Once the address of the delay-loaded function is obtained, __delayLoadHelper fixes up calls to that function so future calls go directly to the delay-loaded function. Note that other functions in the same DLL still have to be fixed up the first time you call them. Also note that you can specify the /DelayLoad linker switch multiple times—once for every DLL that you want to delay-load.

Disadvantages

When the operating system loader loads your executable, it tries to load all the required DLLs. If a DLL can't be loaded, the loader displays an error message. But for delay-loaded DLLs, the existence of the DLL is not checked at initialization time. If the DLL can't be found when a delay-loaded function is called, the __delayLoadHelper function raises a software exception. You can trap this exception using structured exception handling (SEH) and keep your application running. If you don't trap the exception, your process is terminated.

Another problem can occur when _delayLoadHelper does find your DLL but the function you're trying to call isn't in the DLL. This can happen if the loader finds an old version of the DLL, for example. In this case, _delayLoadHelper also raises a software exception and the same rules apply.

If both the DLL and the function are found, the loader will try to load the DLL when a function or a symbol from that DLL is referenced. Since it is loaded now and not at application start up, it will take some time, but things get even worse if while building your DLL you haven't rebased its address to an appropriate one so at the time of function call, the loader will first try to load the DLL and it has to rebase the DLL which has a lot of overhead (for rebasing details, please go through the article Need for Rebasing a DLL). So also, if possible, rebase it properly to load the DLL quickly.

Acknowledgement and References

I would like to acknowledge author Mr Jeffery Richter and his book on Windows OS, which is one of the best books to know about the Windows operating system internals. Parts of this article is taken from the book and examples were added to simplify things.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
Hi I am Sachin Sangoi from Mumbai. Working in VC++ from 9 years (From July 2004).Completed BE Electronics + PG CDAC + MBA Finance.
I would like to thanx Mr Sameer Vasani, my team and my friend Rahul bhamre from whom i learnt a lot.They have been a great help.
Thanx 2 all my friends especially Rahul B, Sandeep C, Sandeep K, Govind P, Rohit P, Pratik P who have all been there when needed.

Happy Coding Smile | :)

Comments and Discussions

 
GeneralMy vote of 2 Pin
Fernando Gonzalez Sanchez5-Apr-16 14:28
Fernando Gonzalez Sanchez5-Apr-16 14:28 
GeneralMy vote of 5 Pin
zhq423-Oct-13 20:06
zhq423-Oct-13 20:06 
GeneralFYI: Can't use #pragma(...) in MSVC 2005 Pin
EmergentComprehension2-Aug-07 7:41
EmergentComprehension2-Aug-07 7:41 
GeneralRe: FYI: Can't use #pragma(...) in MSVC 2005 Pin
Albert Holguin3-Jul-13 11:58
professionalAlbert Holguin3-Jul-13 11:58 
GeneralRe: FYI: Can't use #pragma(...) in MSVC 2005 Pin
™byTM9-Oct-13 22:23
™byTM9-Oct-13 22:23 
GeneralUsing /DELAYLOAD from Developer Studio .NET Pin
ICantChangeMyAcct27-Dec-06 14:36
ICantChangeMyAcct27-Dec-06 14:36 
You can put a list of DLLs to delay-load in the Linker/Input section of the properties for a module. BE SURE TO SEPARATE THE DLL NAMES WITH SEMICOLONS, NOT WITH SPACES AS FOR ADDITIONAL DEPENDENCIES, OR YOU WILL TEAR YOUR HAIR OUT FOR HOURS TRYING TO FIGURE OUT WHY THE LINKER IS IGNORING /DELAYLOAD FOR THE DLLS!!
GeneralDepends not showing delay load dependency Pin
Glen_Summers6-Jun-06 0:00
Glen_Summers6-Jun-06 0:00 
GeneralError handling with delay loading Pin
Tomer Margolin18-Oct-05 6:25
sussTomer Margolin18-Oct-05 6:25 
GeneralDLL Unloading Pin
Gilius6-Apr-05 21:29
Gilius6-Apr-05 21:29 
GeneralRe: DLL Unloading Pin
Sachin R Sangoi26-Apr-05 4:17
Sachin R Sangoi26-Apr-05 4:17 
GeneralRe: DLL Unloading Pin
ETA3-Jun-05 2:15
ETA3-Jun-05 2:15 
GeneralRe: DLL Unloading Pin
Albert Holguin3-Jul-13 12:05
professionalAlbert Holguin3-Jul-13 12:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.