Trying to find out how to build DLLs for a beginner or even experienced programmer can be complicated to configure and use. This article is to post a simple method of building a DLL and then using that DLL in a project with no effort other than needing to include the header file. All you will need is the class already designed and ready to become a DLL file. Even though this is probably some novice stuff, it is believed some experience in working with the MSVS projects are needed. In addition, the advanced person might find some finer points here that could be useful.
Some people might find it hard to research on the Internet useful ways of building DLLs the very simple way. The information in this document is actually a collection of information found on this site and other sites on building DLLs so it is nothing new (only pulling together their efforts). A few articles relate in detail on how to build DLLs and highlights the finer points of what a DLL actually is and how to use it. I suggest reading them first to find broader definitions.
However, it seems that a lot of effort to the novice "DLL Builder" is lacking or too complicated to understand thereof. You may have heard from someone it is easy to build DLLs but trying to figure out how it all pulls together can be an effort in its own. Some articles do not seem to also highlight the importance of directory locations. A DLL, its library and header file(s) must all be in a findable directory that can either be a Windows directory or somewhere where the compiler can find them. Otherwise you may encounter frustrating compiler problems if one or all of the DLLs file are not found, which usually results in an unusable circumstance.
Using the code
There are no code attachments other than comment areas. This should be simple enough to figure out by working alongside in your MSVS environment. What you will need to do is:
- Have a class already prepared that needs to be a DLL file.
- Start a new DLL project
- Insert MACRO definitions in your “StdAfx.h” file.
- Add easy including of the DLL libraries in the main “foo.h” file.
- Add some project preprocessor MACROs.
- Make batch files for the “Post Builds” - to appropriately copy library, header and DLL files to findable directory(s).
- It is assumed that you already created your class, so this step is bypassed.
- First is the easy part. Start up “Microsoft Visual Studio Visual C++”. Select “File->New” to pull up the creation dialog. Under the “Projects” tab button, select “MFC AppWizard (DLL)”. Enter the project name and directory to be used then click “OK”. The rest of the options are not necessary, so select what you want to do in the rest of the Wizard and click “Finish”.
What typically happens after you started the new project is that a source code and header file has been created for you. These are not really needed if you already have the code you are going to build. Only the preset definitions for the project are needed from this step. It is suggested that you just empty the files created by highlighting and deleting the source and header files created by the Wizard. Do not edit the “StdAfx” files yet as these are needed.
The point in this step is to simply copy and paste your class (“foo”) into the header and source files created. It should be a simple concept to grasp, but if you are skeptical you can alternatively just add your “foo” source file and header file into the project so that it is built.
You will next begin the editing part. You must be able to make the build compile as a DLL file correctly for usage. DLL files use a combination of Exporting and Importing. When this is the build project you will need to “Export”. When it is being included in another project that does not use the source code, you will need to “Import”. This is probably the harder part of understanding the DLL as it is not necessarily implemented for you and requires a little effort before understanding. As a side note, the “resource.h” is only required by DLLs that have dialogs in them. In this case, you will have to remember that you may have several “resource.h” files then and will have to include a full path statement to each “resource.h” file. This article will show in the following example what is probably the best method (keeping in mind that if a project needs this resource file it must manually be added to the project including the full path to it).
- Edit the “StdAfx.h” file and include the following MACROS and header file “resource.h”. <PRE lang=c++>StdAfx.h
// MSVS included headers, definitions, etc.
// Somewhere near the bottom
//This is the project macro preprocessor definition
//you will be adding shortly.
//This is to be used for the class header file.
#define DLL_BUILD_MACRO __declspec(dllexport)
#define DLL_BUILD_MACRO __declspec(dllimport)
#ifndef _DLL_BUILD_ //Why do this? Is it necessary? Yes.
#define _DLL_BUILD_ DLL_BUILD_MACRO
//make sure resources are included here, if desired,
//to prevent ambiguous
//callings to different resource.h files.
// Rest of file
- Next we go ahead and edit the main header file of your DLL code. Only a few simple lines need be added to support accurate DLL building and usage: <PRE lang=c++>foo.h
// Miscellanous here
/*This part automatically includes any libraries when called.
When this file is built within the DLL project,
it will not be called because
of our preprocessor macro definition “_FOO_DLL_”.
However, when this file is called from another project,
not part of this build,
it appropriately chooses the correct library and
includes them for you.
WHAT this means is that you will not have to
add the library to the project link settings
for a project that requires this DLL. This helps to
avoid the tedious task of
linking to several custom DLLs.
Note there are two different libraries here and
probably not necessary but give
you an idea of how to separate debug versions
from release versions.*/
//You will be building a debug program that
//uses this file, so in this case we
//want the debug library.
#pragma comment( lib, “food.lib” )
//You will be building a release program that
//uses this file, so in this case we
//want the release library.
#pragma comment( lib, “foo.lib” )
#define _DLL_BUILD_ //Makes sure there are no compiler errors.
class _DLL_BUILD_ foo
// Your members
// Your functions
- To continue, edit the “foo.cpp” file and make sure you include the appropriate headers. <PRE lang=c++>foo.cpp
#include “stdafx.h” //place first
- This next step requires that you actually add the MACROS into the project settings. In the menu tool bar, go to “Project->Settings…” or press Alt+F7 alternatively. Click the “C/C++” tab. Under “Preprocessor definitions:” add the macro definitions “
_FOO_DLL_” and “
DLL_EXPORTS” at the end of the list of other macro definitions. Be sure to separate each new MACRO with a coma (“,”). Make sure to do this for the release version too, as you will have to redo these next steps for each type of build. Make sure to build with any “debug info” and/or “browse info” if this is a debug version and if you want to debug the DLL later using the MSVS debugger.
- Next you will want to prepare for the last step. Go to the “Post-build step” tab under the same dialog. Under “Post-buid command(s):” click an empty space and enter “Debug.bat”. For the release version go to in the left pane and in the combo box “Settings For:” select “Win32 Release”. Enter like you did before in “Post-Build command(s)” but not “Debug.bat” and instead “Release.bat”. This is it for all the project settings.
- Now to build the batch files. Create a blank file. You will be adding command line codes that will copy your files to a findable directory. The point here is that if you may have a ton of DLLs and it will be easier to have all the needed components in one directory. This is easier versus linking to several directories. Below are the suggestions used in this article that maybe you will want to consider for adding other options:
Copy “Debug\foo.lib” “c:\<libraries dir>\food.lib”
REM copy the dll file to the windows system32
REM directory to make the DLL easily
REM accessible. Note that you will have to install or include the
REM dll file in your distribution package for the program that uses it.
Copy “Debug\foo.dll” “c:\%system dir%\system32”
Copy “foo.h” “c:\<headers dir>”
Copy “Release\foo.lib” “c:\<libraries dir>”
REM copy the dll file to the windows system32 directory
REM to make the DLL easily accessible.
REM Note that you will have to install or include the dll
REM file in your distribution package.
REM Unfortanetly this will overwrite any other DLL files
REM such as the Release/Debug version,
REM so accurate update compilations are needed.
REM You will have to note this yourself
REM before distributing to the public.
Copy “Release\foo.dll” “c:\%system dir%\system32”
Copy “foo.h” “c:\<headers dir>”
You are completely finished. Providing you have already pre-tested your class and considered where your library, header and DLL files are being copied you should receive no problems at all. Your class should be a DLL file that can be easily used in future projects without much work. All you have to do with this information is to know that you only need to include the header file and everything is done for you. Everything is made as easy and simple as possible for you on in out.
Some reminders are that the DLL file must be accessible. This article references using the “c:\windows\system32” directory. This may be a bad idea if you want to later retrieve that DLL file and must find it in the large collection of DLLs probably existing already in that directory. It can also be annoying if you later decide to change the name of the project and build under the different name. In that case you will have to find the old DLL file and manually remove it or just leave it there.
Alternatively you can copy the DLL file(s), library file(s) and header file(s) to the project directory that will be using it. However, if you decide to use the same DLL in another project you will have to go back and add a copy command line(s) in both the “Debug.bat” and “Release.bat” files and then rebuild the project to have them copied.
Also note that in MSVS it is easy to add custom directories for new header directories to search, but unfortunately not DLL directories. Go under “Tools->Options” in the menu bar and then under the “Directories” tab button. Where “<libraries dir>” above in the batch file should be included under “Library files” in the “Show directories for” combo box and “<headers dir>” in the “Include files”. Some MACROS may seem repetitive or not in use in this article. However, the compiler, when building, requires this type of style for both the DLL project and the project using that DLL. If you find that some are not needed you can remove them yourself. This code is designed so that they are there and readably Accessible. Testing shows that for both the DLL build and the project using that DLL build require these types of MACRO setups for usage. Other possibilities and locations exist.
Points of Interest
Figuring out Firewalls, UNIX and why mail programs show the contents automatically in Windows.
- No reformatting necessary.