Your import results in the function being linked using what is known as load-time or implicit linking. That is the executable contains meta data that tells the OS loader to load the DLL, and then bind to the functions that you named. If this load-time linking process fails, then the executable cannot be loaded.
You have a couple of options to avoid load-time linking, and thereby allow your program to be resilient to linking failures.
Delay-loading the DLL
Add the delayed
directive to your function import. The documentation says:
To postpone the loading of the library that contains the function to
the moment the function is actually needed, append the delayed
directive to the imported function:
function ExternalMethod(const SomeString: PChar): Integer; stdcall;
external 'cstyle.dll' delayed;
delayed ensures that the library that contains the imported function
is not loaded at application startup, but rather when the first call
to the function is made.
The documentation contains other useful topics that go into more detail, and cover how to handle errors:
Explicit loading and binding to the DLL
The delayed
directive is merely a concise way to get the compiler to arrange explicit loading of your DLL. You can do the same yourself manually using LoadLibrary
and GetProcAddress
.
- Call
LoadLibrary
to load the DLL. Either supply a full path to the DLL, or just its name. In the latter case you rely on the DLL search order to locate the DLL. The call to LoadLibrary
yields a module handle.
- Call
GetProcAddress
to obtain the address of a named function pointer. You must supply the module handle from step 1.
- Call the function pointer returned from step 2.
- When you no longer need to call the function, use
FreeLibrary
to unload the DLL.
At each step of the way you must check the function return values in case of error. How to handle errors is documented for each Win32 API function in the MSDN documentation (as linked to above). For example, if the DLL cannot be found, then LoadLibrary
returns 0
. You must detect that and deal with the consequences accordingly.
Discussion
Although the delayed
directive is very convenient, I personally have never used it. In my experience, whenever I have needed to link explicitly I've always found that I needed some extra flexibility that is not offered by delayed
. Perhaps my needs are special, but do not be surprised if you find yourself leaning towards explicit calls to LoadLibrary
and GetProcAddress
.
As an example, just today I found myself using LoadLibraryEx
because I wanted to pass the LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
flag. That sort of fine grained control is not available when you use delayed
.