1

Often when trying to run an EXE which uses a DLL, if the DLL is missing you get a standard Windows error:

The program can't start because XXX.dll is missing from your computer. Try reinstalling the program to fix this problem.

This seems to be built-in to the EXE before any of your code gets called... how does it work, and how does this get set up when building a project in Visual Studio?

edit:

In my specific scenario I actually have a DLL which has "static" dependencies on other DLLs so if those aren't present, registering my DLL fails which is a little hard to diagnose. But I'd rather not manually list ever DLL function used as there are lots!

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589

1 Answers1

7

When you link to a DLL there are two ways to do this, implicit linking and explicit linking. What you are encountering is a failure of implicit linking.

Implicit linking operates through something called the import table contained in the executable image which uses the PE (Portable Executable) format. The PE format defines both import and export tables. The export table contains the list of functions exported by a DLL, and their entry points. The import table contains the implicit dependencies on other modules.

When an executable starts the loader reads the import table and then tries to load all the DLLs referenced and all the functions in those DLLs. This can fail if the DLL is not found, if the DLL fails to load properly, or if the DLL does not contain the referenced functions. In your case it is failing because the loader did not find XXX.dll in the DLL search path.

The linker will generate the import table. In C++ this is typically done via the .lib file for that DLL.

Explicit linking is where your code calls LoadLibrary and GetProcAddress to load a DLL and its functions. Typically this approach is used when you want to write an app that can run on different systems. For example you may wish to use certain functions that are only present on certain versions of the OS, but degrade to some other behaviour when run on an older version of the OS.

The term static should not be used when referring to linking to DLLs. Static linking is when the implementation of a function is included in an image rather than contained in an external library.

The MSDN article on the topic explains all this and more.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Your linked MSDN page uses the term 'static'... anyway the short answer is by adding the DLL's associated .lib, I cause VS to implicitly link the DLL? But if I don't add that .lib I get linker errors since I call methods declared in the .h files. Can I tell VS _not_ to implicitly link the DLL but still work the same way otherwise? – Mr. Boy Feb 09 '11 at 11:27
  • 1
    @John It mentions the term *static* when it lists the other commonly used terms for *implicit* linking. In my view the use of *static* to describe *dynamic* linking is mis-use. The problem with using the term *static load* is that it is too easy to confuse with *static linking* which is altogether different. – David Heffernan Feb 09 '11 at 11:47
  • @John Your problem is not related to implicit vs explicit linking. The problem is that the DLL is not in the search path. You need to put it in the search path. I don't know what's the best way to solve that. If you told us about the provenance of the DLL then we could advise you where to put it. – David Heffernan Feb 09 '11 at 11:49
  • I'm not sure before the DLL gets loaded there is a way to set the search-path, an external app is loading the main DLL as a plugin, the idea is the plugin's resources (DLLs, artwork, etc) will be in another folder it determines at runtime. This is fine for normal use but means the DLL can't be loaded even to be registered without the other DLLs present. – Mr. Boy Feb 09 '11 at 14:32
  • 1
    @John This is now a different question. I answered your original question. I suggest you ask a new question and explain all the details of how the various exe and dll files fit together. You should also accept some of your other questions that have good answers (starting with this one of course!!) – David Heffernan Feb 09 '11 at 14:36
  • @John: I think your next question is already answered [here](http://stackoverflow.com/questions/327093/add-custom-dll-search-path-application-startup). You need to add a call to `SetDllDirectory` to add the DLL's directory to the search path. – Cody Gray - on strike Feb 10 '11 at 04:36
  • @Cody Gray and exactly how do I do that magically when I supply a DLL as a plugin. I don't have any app running that can do this. – Mr. Boy Feb 10 '11 at 11:05
  • @John: So I assume you're loading the DLLs with `LoadLibrary` and `GetProcAddress`? If that's the case, you can specify the full path to the DLL. I'm not sure how you do it magically. You need a lot less magic when your requirements are clear. – Cody Gray - on strike Feb 10 '11 at 11:24
  • BTW, delay-load DLLs are a good solution to this problem, as they allow the programmer to have all the convenience of implicit dynamic linking, but the error recovery abilities of explicit dynamic calls. – Ben Voigt Oct 04 '13 at 22:26
  • Also, "static dependency" is an accurate term here, the dependency is created at build time by linking with the import library, which is a special kind of static library, and doesn't change thereafter. (Obviously the linking with the DLL exports is still dynamic) – Ben Voigt Oct 04 '13 at 22:27
  • @Ben Does depend on point of view. Implicit linking has both static and dynamic parts to it. The bind is part static, part dynamic. – David Heffernan Oct 04 '13 at 22:31