Is it possible to handle a missing dll file gracefully in a Delphi application?

Does anyone know if it can be gracefully checked and processed by a missing dll file in a Delphi application? For example, my code has this function declaration:

function KFUNC(Arg1, Arg2, Arg3, Arg4: DWord): longint stdcall; external 'KL2DLL32.DLL' name ' _KFUNC@16 '; 

... which, of course, requires that the KL2DLL32.DLL dll file be found on the system, otherwise my application will not start. I am wondering if there is another way to encode, so my application can check for the existence of the dll file and then process it accordingly. Obviously, the goal will be that my application will still start normally, even if the dll file is missing. Thanks.

+6
source share
2 answers

Your import results in a function binding using what are called load times or implicit bindings. This executable file contains metadata that tells the OS loader to load the DLL and then bind to the functions that you named. If this process of linking download times is not performed, then the executable file cannot be downloaded.

You have several options to avoid load time binding and thereby allow your program to be resistant to crash binding.

DLL load delay

Add a delayed directive to the function import function. The documentation states:

To defer loading the library that contains the function at the moment the function is really needed, add the delayed directive of the imported function:

 function ExternalMethod(const SomeString: PChar): Integer; stdcall; external 'cstyle.dll' delayed; 

delayed ensures that the library containing the imported function is not loaded when the application starts, but rather the first time the function is called.

The documentation contains other useful topics that are described in more detail and describe how to handle errors:

Explicit loading and binding to DLL

The delayed directive is just the shortest way to get the compiler to explicitly load your DLL. You can do the same manually using LoadLibrary and GetProcAddress .

  • Call LoadLibrary to load the DLL. Either put the full path to the DLL, or just its name. In the latter case, you rely on a DLL search to find a DLL. A call to LoadLibrary gives a module handle.
  • Call GetProcAddress to get the address of the named function pointer. You must provide the module handle from step 1.
  • Call the function pointer returned from step 2.
  • When you no longer need to call a function, use FreeLibrary to unload the DLL.

At each step, you must check the return values โ€‹โ€‹of the function in case of an error. How to handle errors is documented for each Win32 API function in the MSDN documentation (as described above). For example, if the DLL cannot be found, then LoadLibrary returns 0 . You must discover this and handle the consequences accordingly.

Discussion

Although the delayed directive is very convenient, I personally have never used it. In my experience, whenever I needed to explicitly specify a link, I always found that I needed additional flexibility that delayed did not offer. My needs may be special, but don't be surprised if you find yourself in the direction of explicit calls to LoadLibrary and GetProcAddress .

As an example, only today I discovered that I used LoadLibraryEx because I wanted to pass the flag LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR . This type of fine-grained control is not available if you use delayed .

+11
source

When a function is declared as such, your program cannot make the missing DLL. The OS is trying to resolve the imported DLL function before any bit of your program code starts to run, so there is no code that you can write to do anything about it.

As with Delphi 2010, you can change the function declaration to use the new delayed load function. Add a delayed directive to the end of the declaration:

 function KFUNC(Arg1, Arg2, Arg3, Arg4: DWord): longint stdcall; external 'KL2DLL32.DLL' name ' _KFUNC@16 ' delayed; 

If you are using an older version of Delphi, then your only option is to load the DLL and function at run time, and then handle the errors.

Another advantage of using delay is that there are SetDliNotifyHook2 and SetDliFailureHook2 functions that allow you to assign hooks so that you can handle load notifications and runtime failures, respectively.
Thus, if a given DLL or even a given function is not found at run time, you can register an error, even substitute it with another DLL descriptor or function pointer to satisfy the load.

Both options are discussed in more detail in another question about using DLLs only when required .

+4
source

All Articles