DLL -- Delay loading & Dynamic loading

 

    但行好事,莫问前程。


MSDN 官方详细解释:

 

讲解: Dll的两种使用方式Implicit  linking and Explicit linking 的概念、如何选择、如何具体实施;

https://docs.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=vs-2019

 

Implicit linking, where the operating system loads the DLL at the same time as the executable that uses it. The client executable calls the exported functions of the DLL the same way as if the functions were statically linked and contained within the executable. Implicit linking is sometimes referred to as static load or load-time dynamic linking.

Explicit linking, where the operating system loads the DLL on demand at runtime. An executable that uses a DLL by explicit linking must explicitly load and unload the DLL. It must also set up a function pointer to access each function it uses from the DLL. Unlike calls to functions in a statically linked library or an implicitly linked DLL, the client executable must call the exported functions in an explicitly linked DLL through function pointers. Explicit linking is sometimes referred to as dynamic load or run-time dynamic linking.

 


Good Explains from CodeProject.com


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

实现dynamic loading的一般步骤。 需要使用windows 的GetProcAddress() 函数从dll定位出其中的函数地址。

以下为Hans Dietrich在此文中的总结,另外,在carsim公司为unreal engine4提供的插件中,代码中使用carsim dll时使用的为dynamic loading 的方式(https://www.unrealengine.com/marketplace/en-US/product/carsim-vehicle-dynamics),与下面步骤相同。

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值