.: Home :: Contact Us :.  
  



Hans Dietrich Software

free and licensed software

   

How to Link to a DLL

There are two ways to link to a DLL from a Visual C++ program:
  1. Implicit linking - This is the most common way to link to a DLL. It assumes you have the DLL, its import library file (.lib) and its header file (.h).
  2. Explicit linking - This technique is used when a .lib and/or a .h file are not available for the DLL. It involves using the Win32 APIs LoadLibrary() and GetProcAddress().
There are a few more steps involved with explicit linking, but aside from that, both techniques will allow you to call a function in a DLL from a Visual C++ program. The following sections discuss these techniques in detail.

Implicit Linking

screenshot

Consider the directory structure at the left. This is a fairly typical way to set up a VS project, with the app source and .vcxproj/.sln files in src, the additional include (.h) files in include, and DLL .lib files in lib. Given this structure, how do we set up Visual Studio so that it can find all the files it needs to compile and link the application?

Setting Compile Directories

First, we have to tell the compiler where to find the DLL's header file, MyDll.h, which we have used in a #include in MyApp. In the MyApp property pages, we add ..\include to the Additional Include Directories:

screenshot

Note that with this and all other directory paths, a relative path is used, which makes it easy to copy the project to another directory or disk. In this case, the relative path to the header file is ..\include, since the project directory is src.

Setting Link Directories

Now that the compiler is happy, we have to tell the linker where to find the .lib file for the DLL. Again in the MyApp property pages, we add ..\lib to the Additional Library Directories:

screenshot

and we also tell the linker that the DLL function declarations can be found in MyDll.lib:

screenshot

Where is the DLL?

The above steps will compile and link MyApp. The only remaining question is, how does MyApp find the DLL when it is run? With the tightened security of Vista and Win7, you should not even consider putting an application DLL in the Windows or System32 directories. Application DLLs belong in the same directory as the application EXE. When you are developing a new application, you have two choices: put a copy of the DLL in your Debug directory, or make a bin directory where you copy the application EXE with a post-build command.

It is important that you do not copy development DLLs anywhere to the Windows path, where other applications may pick them up by mistake, or where you might confuse an older DLL with the one you are trying to debug. Be very careful about where you copy DLLs.

To further protect yourself when developing a new DLL, it is good practice to implement a function in the DLL that will allow you to get its version number, to verify that you are loading the correct DLL.

Explicit Linking

When you explicitly load a DLL, you do not have to specify additional include or library directories. However, the DLL must still be accessible to the EXE. Once again, application DLLs belong in the same directory as the application EXE.

Even though you do not have a DLL header file, you still must know the function prototype of the function you want to call. As an example, suppose you want to call the function IsThemeActive() which you know is in the Windows DLL UxTheme.dll. After checking on MSDN, you see that the function prototype is

BOOL IsThemeActive(void);
so you write the following typedef:
typedef BOOL (__stdcall *PFNISTHEMEACTIVE)();
(Note: all Windows APIs use __stdcall calling convention.)

Since this is a Windows DLL, it will be on the path, so loading the DLL is simple:

    HMODULE hDLL = LoadLibrary(_T("UxTheme.dll"));
and now you can get a pointer to IsThemeActive():
    PFNISTHEMEACTIVE pIsThemeActive = (PFNISTHEMEACTIVE)GetProcAddress(hDLL, "IsThemeActive");
and you can call the function like this:
    BOOL bThemed = pIsThemeActive();
When you are finished with the DLL, you should unload it like this:
    FreeLibrary(hDLL);