DLL Tutorial For Beginners

I was trying to learn DLLs and nothing was really explaining anything; it was just code for you to look at and wonder what was going on. For this article, I assume you know how to use the features of your compiler, such as setting directory paths and such.

To set up the project, select Win32 Console Application, and on the advanced tab, select DLL and empty project options. DLLs are not as hard as you might think they are. First, make your header file; call this DLLTutorial.h. This file is like any other header file in that it has function prototypes.

#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#include <iostream>

#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

extern "C"
{
   DECLDIR int Add( int a, int b );
   DECLDIR void Function( void );
}

#endif

The first two lines instruct the compiler to include this file only once. The extern "C" tells the compiler that it is okay to use this in C or C++.

There are two ways of exporting functions in VC++:

  1. Use __declspec, a Microsoft-specific keyword.
  2. Create a Module-Definition File (.DEF). The first way is a tad bit easier to do than the second, but both work just fine.

__declspec(dllexport) exports the function symbols to a storage class in your DLL. I defined DECLDIR to do this function when the line

#define DLL_EXPORT

is defined, but also import the functions if the line

#define DLL_EXPORT

is not present in the source file(s). In this case, you will export the functions Add(int a, int b) and Function().

Now, you need to make a source file that you'll call DLLTutorial.cpp.

#include <iostream>
#include "DLL_Tutorial.h"

#define DLL_EXPORT

extern "C"
{
   DECLDIR int Add( int a, int b )
   {
      return( a + b );
   }

   DECLDIR void Function( void )
   {
      std::cout << "DLL Called!" << std::endl;
   }
}

This is where you define all of your functions. Int Add(int a, int b) simply adds two numbers and void Function(void) just informs you that your DLL was called.

Before I show you how to use the DLL, I want to tell you about the Module-Definition File (.def).

Module-Definition File (.def)

A module definition file is a text file with a .def extension. It is used to export the functions of a DLL, much like __declspec(dllexport), but the .def file is not Microsoft specific. There are only two required sections in a .def file: LIBRARY and EXPORTS. Take a look at a basic .def file and then I'll explain.

LIBRARY dll_tutorial
DESCRIPTION "our simple DLL"
EXPORTS
   Add @1
   Function @2

The first line, 'LIBRARY', is one of the required sections. This tells the linker what to name your DLL. The next section labeled 'DESCRIPTION' is not required, but I like to put it in. It writes the string into the .rdata [from MSDN] and it tells people who might use the DLL what it does or what it's for. The next section labeled 'EXPORTS' is the other required section; this section makes the functions available to other applications and it creates an import library. When you build the project, not only is a .dll file produced, but an export library is produced with the extension .lib. In addition to the previous sections, there also are four other sections labeled NAME, STACKSIZE, SECTIONS, and VERSION. I will not cover these in this tutorial. but if you search the Internet, I think you'll find something. One more thing: A semicolon (;) starts a comment, as '//' does in C++.

Now that you have created your DLL, you need to learn how to use it in an application. When the DLL was built, it created a .dll file and a .lib file; you will need both.

Implicit Linking

There are two ways to load a DLL; one way is the easy route and the other is more complicated. The easy route is just linking to your .lib file and putting the .dll file in your new projects path. So, create a new Empty Win32 Console project and add a source file. Put the DLL you made in the same directory as your new project.

#include <iostream>
#include <DLLTutorial.h>

int main()
{
   Function();
   std::cout << Add(32, 58) << "\n";
   return(1);
}

You must link to the DLLTutorial.lib file. I did it in Project Settings, but you could use

#pragma comment(lib, "DLLTutorial.lib")

instead. Please note that I set the compiler to look into my DLL folder for the .lib file and set it to look in the directory for the DLL header. If you don't want to do this, you can always put them in the directory with your new project and use "" (quotes) instead of <>. That's how you load a DLL the easy way.

Explicit Linking

The harder way to load a DLL is a little bit more complicated. You will need function pointers and some Windows functions. But, by loading DLLs this way, you do not need the .lib or the header file for the DLL, only the DLL. I'll list some code and then explain it.

#include <iostream>
#include <windows.h>

typedef int (*AddFunc)(int,int);
typedef void (*FunctionFunc)();

int main()
{
   AddFunc _AddFunc;
   FunctionFunc _FunctionFunc;
   HINSTANCE hInstLibrary = LoadLibrary("DLL_Tutorial.dll");

   if (hInstLibrary)
   {
      _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
      _FunctionFunc = (FunctionFunc)GetProcAddress(hInstLibrary,
         "Function");

      if (_AddFunc)
      {
         std::cout << "23 = 43 = " << _AddFunc(23, 43) << std::endl;
      }
      if (_FunctionFunc)
      {
         _FunctionFunc();
      }

      FreeLibrary(hInstLibrary);
   }
   else
   {
      std::cout << "DLL Failed To Load!" << std::endl;
   }

   std::cin.get();

   return 0;
}

The first thing you'll notice is that you included the file "windows.h" and removed "DLL_Tutorial.h". The reason is simply because Windows.h contains many Windows functions and you will need only a few right now. It also contains some Windows-specific variables that you will use. You can remove the DLL's header file (DLL_Tutorial.h) because, as I've stated before, you don't need it when you load DLLs this way.

The next thing you'll notice is an odd-looking piece of code in the form of:

typedef int (*AddFunc)(int,int);
typedef void (*FunctionFunc)();

Those are function pointers. Because this is a tutorial about DLLs, an in-depth look at function pointers is out of the scope of this tutorial; so, for now just think of them as aliases for the functions the DLL contains. I like to name them with the word "Func" attached on the end. The (int,int) part is the parameters that the function takes; for example, the Add function takes in two ints; therefore, you need those as the parameters for the function pointer. The Function function takes no parameters, so you can leave that blank. The first two lines in main() are the function pointers being declared so that you can set them equal to the functions inside the DLL. I just like to define them beforehand.

An HINSTANCE is a Windows dat type that is a handle to an instance; in this case, that instance will be the DLL. You get the instance of the DLL by using the LoadLibrary() function; it takes in a name as the parameter. After the call to LoadLibrary, you must check to see whether the function succeeded. You can do so by checking whether the HINSTANCE is equal to NULL (defined as 0 in Windows.h or one of the headers Windows.h includes). If it is equal to NULL, the handle is not valid, and you must free the library. In other words, you must free up the memory that the DLL was taking up. If the function succeeded, your HINSTANCE contains the handle to the DLL.

Once you have the handle to the DLL, you now can retrieve the functions from the DLL. To do that, you must use the GetProcAddress() function, which takes in as parameters the handle to the DLL (you can use the HINSTANCE) and the name of the function. You set the function pointers to contain the value returned by GetProcAddress() and you must cast GetProcAddress() to the function pointer that you defined for that function. For example, for the Add() function, you must cast GetProcAddress() to AddFunc; this is so that it knows the parameters and return type. Now, it would be wise to make sure that the function pointers are not equal to NULL and that they hold the functions of the DLL. That is just a simple if statement; if one of them does equal NULL, you must free the library as mentioned above.

Now that the function pointers hold the functions of the DLL, you can use them, but there is one catch: You cannot use the actual function name; you must use the function pointer to call them. After that, all you need to do is free the library and that's it.

Now you know the basics of DLLs. You know how to create them, and you know how to link them with two different methods. There is still more to learn about this, but I'll leave that to you to look for and for better writers to write.



About the Author

Joe P.

I love to play guitar, and I love to program. Thats it, my life is boring. :)

Downloads

Comments

  • not good

    Posted by julian on 11/16/2014 06:11pm

    followed directions. doesn't work. Visual studio express 2013. disappointing. For all the effort you went to in writing this up, why not do the tiny extra bit of effort and explain how to do the linking? at least that way I'd know if I did something different to you (pretty sure I am linking the .h into the dll using project and linking the .lib file in the right place though - I did look it all up)

    Reply
  • GOOD and easy to understand

    Posted by mahendra on 10/27/2014 03:02am

    Nice article . Ya this article is for beginners as it is written in simple understandable lang. Please write the other part of the article. I am waiting.

    Reply
  • thanks

    Posted by Venu on 10/07/2014 02:14pm

    Thank you very much for the simple tutorial

    Reply
  • http://www.skinbleachings.com

    Posted by Yakinican on 08/23/2014 08:11am

    I tried using the Microsoft Visual C 2008 SP1 ++. But I do not find a rebuild on the program that I use. How then do I know the result of the tutorial above? Sorry my question is very stupid, because I was just learning about the C ++.

    Reply
  • DLL

    Posted by Ahmad Naeem on 07/16/2014 11:29pm

    I am creating same thing as you mention in your tutorial.But when i build my project than lot some linker error came. Please can you tell me the problem.

    Reply
  • Sr. SE

    Posted by 8Dmax on 03/05/2014 08:30am

    #define DLL_EXPORT should be in front of #include "DLL_Tutorial.h" in DLLTutorial.cpp.

    Reply
  • Confusing tutorial

    Posted by anonymous on 04/25/2013 12:08pm

    Well i find your tutorial really confusing ,, you talked about lot of stuffs and you did not make it easy for C juniors ,

    • I agree!

      Posted by CTlod on 05/31/2014 12:35pm

      I agree!

      Reply
    Reply
  • utility and dll

    Posted by on 01/24/2013 11:26pm

    Hi, i have one utility and have to automatically install the one dll to it. for that it need to ask about the utility compatibility like version and it also ask for the utility is pirate version or original version . if it is original version it need to ask for the identity and have to give the full access to it . otherwise some properties of dll has to be hidden…. then only it has to install on utility. give me some ideas to do it.

    Reply
  • utility and dll

    Posted by on 01/24/2013 11:25pm

    Hi, i have one utility and have to automatically install the one dll to it. for that it need to ask about the utility compatibility like version and it also ask for the utility is pirate version or original version . if it is original version it need to ask for the identity and have to give the full access to it . otherwise some properties of dll has to be hidden…. then only it has to install on utility. pls give me some ideas to do it.

    Reply
  • Re:

    Posted by icon-design on 09/13/2012 09:32pm

    You commit an error. I can prove it. Write to me in PM, we will communicate. P.S. Please review our icons for Windows and windows12icons.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

  • The hard facts on SaaS adoption in over 80,000 enterprises: Public vs. private companies Mid-market vs. large enterprise GoogleApps, Office365, Salesforce & more Why security is a growing concern Fill out the form to download the full cloud adoption report.

Most Popular Programming Stories

More for Developers

RSS Feeds