DLL -- Delay loading & Dynamic loading

 

 


Perfect: https://www.codeproject.com/Articles/6299/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part-4


Dynamic Loading

Normally, when you link to a DLL via a LIB file (for example, the MFC DLLs), the DLL is loaded when your application starts up. This kind of loading is referred to as implicit linking, because the system takes care of the DLL loading for you - all you have to do is link with the LIB file.

Dynamic loading又称dynamic linking, explicit linking.

Dynamic loading (a.k.a. dynamic linking) means that your application loads a DLL just before you call a function in the DLL. For dynamic loading, you do not use a LIB file. Instead, what you do is call a pair of Win32 API functions (LoadLibrary/GetProcAddress) that load the DLL and then retrieve the address of a function in the DLL. Because you explicitly invoke these APIs, this kind of loading is also referred to as explicit linking.

To summarize:

  • implicit linking - DLL is loaded automatically when your app starts
  • explicit linking - you write code to load DLL


Why Use Dynamic Loading?

Before I get into the details of dynamically loading DLLs, let me first answer the question: When is it desirable to dynamically load a DLL? Here are the typical scenarios:

  1. You don't have a lib file to link with - this is a pretty lame reason, since if you worked at it you could generate a LIB file. On the whole, though, generating a LIB file is probably more work than just using LoadLibrary/GetProcAddress to dynamically load a DLL.
  2. A DLL may not always be present - if you want to provide for some graceful program degradation, you must dynamically load any DLL that may or may not be present on the target machine (example: UXTHEME.DLL, which exists only on XP). If you used implicit linking, your application would never have the chance to degrade gracefully - the system simply would not allow your app to start, and would instead display some alarming message to your user.
  3. You need to support multiple feature sets - this is one of the historically valid reasons for using dynamic loading. If you have a product that supports many different features, and you want to load only those features that the customer has paid for, then what you do is package each feature set in its own DLL, and ship the DLL to the customer when he orders it. This is also a very convenient way to add new features (read: plug-ins) to your product, essentially making it open-ended.
  4. You need to support multiple platforms - this is also one of the historically valid reasons for using dynamic loading. You need to support multiple platforms (Win98, Win2000, WinXP) and each platform requires slightly different code for some reason. A simple solution is to segregate the code for each platform in its own DLL.
  5. You need to speed up the time it takes to load your application - this is another historical reason for using dynamic loading. You will start thinking about this when customers start complaining about how slow your app is to load. The idea is to identify what DLLs are necessary to display the core UI, and then dynamically load all the other DLLs that your app needs.

Delay Loading

If you have been paying close attention, you will be wondering by now why I am using the term "historical". If you think there is a more modern way to implement dynamic loading other than the LoadLibrary/GetProcAddress technique, you are correct. In scenarios 4 and 5 above, you may be able to use a technique called delay loading to effectively implement dynamic loading in your application, with very little work.

OK, so what is delay loading? This is a new feature introduced with Visual C++® 6.0 that is implemented by a new /DELAYLOAD linker option. The interesting thing about delay loading is that it is not dependent on any operating system support - once you have linked your application with delay loading under VC 6 or later, it will work on any Windows OS. This is because the VC++ 6 linker actually generates code (no previous MS linker had ever generated code before). When you use delay loading, your VC++ application works just like a VB application - the DLL you have specified to be delay loaded won't be loaded until you make a call to one of its functions (personally, I think Microsoft missed a trick by not calling this "Just In Time Loading"). In practice, what you would do is test some condition, and then execute some code depending on the condition:

if (IsWinXP())
    DisplaySpiffyXPThemedUI();
else
    DisplayBoringUI();

Inside DisplaySpiffyXPThemedUI(), you know it is safe to call the functions in UXTHEME.DLL, because you've already verified that you're running on XP. The first UXTHEME.DLL function that you call will cause UXTHEME.DLL to be loaded by the stub that the linker generated.

The neat thing is that all this happens transparently; you don't have to make any code changes at all to use delay loading (except, of course, you have to make sure that UXTHEME.DLL is present on the machine, before attempting to call its functions).

NOTE:

There is one difference between delay loading and dynamic loading:

with delay loading, you still need to link to a .LIB file, because the linker needs this information in order to create the delay-loading stub.

 

 

Using Dynamic Loading

The general steps to achieve dynamic loading. The windows need to use GetProcAddress()a function from the function address dll positioned therein.

The following is Hans Dietrich summarized in this article. In addition, the plug-in carsim company unreal engine4 provided, use the code when using carsim dll for dynamic loading of ( https://www.unrealengine.com/marketplace/en -US / Product / CarSim-Vehicle-Dynamics ), and following the same steps.

use GetProcAddress() to get the address of a function in the DLL. Here are the steps:

  1. Load the library:
    CXLoadLibrary lib;
    if (!lib.LoadLibrary(_T("DLL3.dll")))
        return;
    
  2. Define a typedef for the function in the DLL - note the use of __stdcall:
    typedef void * (__stdcall *CreateFn)();
    
  3. Get the address of the function:
    CreateFn pfnCreate =
        (CreateFn) GetProcAddress((HINSTANCE) lib, _T("CreateDll3"));
    
  4. Call the function via the typedef'd variable:
    void * objptr = pfnCreate();
    

Warning: The examples presented in this article have skimped on error checking. When using GetProcAddress(), you must check the return address!

 

Ref:

https://www.codeproject.com/Articles/6299/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part-4

 

Published 341 original articles · 87 won praise · views 220 000 +

Guess you like

Origin blog.csdn.net/qq_35865125/article/details/104334803