Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C++

Basic C++ Win32 DLL

Rate me:
Please Sign up or sign in to vote.
4.44/5 (27 votes)
26 Sep 2013CPOL4 min read 133.9K   50   25
Basic steps of creating and consuming a C++ Win32 DLL.

Introduction

In this article, we will create a small and simple Win32 C++ DLL project using an Empty Project template from Visual Studio 2010 and then create a separate Win32 Console Application to consume the DLL functionalities.

There are many uses of DLL but this article only focuses on how to create and use a C++ Win32 DLL as well as giving you a skeleton on the structure of a C++ Win32 DLL. A C++ Win32 DLL produces binary code. Note that there is also another kind of DLL which is a CLR DLL. CLR DLL does not produce binary code but it generates an Intermediate Language code or IL code which is not covered in this article. CLR DLLs are called managed code while C++ Win32 DLLs are called unmanaged code. CLR codes are those codes made from .NET Framework languages like C#, VB.NET, or with VC++ .NET.

Background

You can simply think of a DLL or Dynamic Link Library as a collection of codes, data, or resources that is packed together into one file. DLL is a great way to distribute and reuse code. For example you have two applications that use arithmetic operations like Addition, Subtraction, Multiplication, and Division, instead of coding the same operations in each application, you can just put these operations inside a DLL (e.g., Math.dll) and reference the DLL from the two applications. In this manner, you only code the math operations once, while your two applications or even your future applications can use the same Math.dll for arithmetic operations.

More of that, it would be easier to understand if we will just see the working code, right? So let's dive into the code project!

Using the code

First, let's create a C++ Win32 DLL using Visual Studio 2010. (It is recommended to use VS 2010 since this was the actual IDE used to build this project. Other version may be used but with some slight differences.)

Let's open Visual Studio 2010 and select "File > New Project > Visual C++ > Win32 > Win32 Project" and name the new project "MyWin32CppDLL" and then Press OK. A Win32 Application Wizard window will popup - click Next button and then select the Application type: "DLL" and tick Additional options: "Empty project" and finally click the Finish button.

Then let's add four files into our project (MyWin32ClassOne.h, MyWin32ClassOne.cpp, MyWin32ClassTwo.h, and MyWin32ClassTwo.cpp). I just wanted to add two classes into our DLL to illustrate that we can add classes as many as we like into a DLL.

Place the below code to their respective files.

MyWin32ClassOne.h

C++
namespace MyWin32DLL
{
    class MyWin32ClassOne
    {
    private:
        int varone;
    public:
        __declspec(dllexport) MyWin32ClassOne();//constructor
        __declspec(dllexport) void Setvar(int val);
        __declspec(dllexport) int Getvar();
    };
} 

MyWin32ClassOne.cpp

C++
#include "MyWin32ClassOne.h"

namespace MyWin32DLL
{
    MyWin32ClassOne::MyWin32ClassOne()
    {
        varone = 123;
    }
 
    void MyWin32ClassOne::Setvar(int val)
    {
        varone = val;
    }
 
    int MyWin32ClassOne::Getvar()
    {
        return varone;
    }
} 

MyWin32ClassTwo.h

C++
namespace MyWin32DLL
{
    class MyWin32ClassTwo
    {
    private:
        int vartwo;
    public:
        __declspec(dllexport) MyWin32ClassTwo();//constructor
        __declspec(dllexport) void Setvar(int val);
        __declspec(dllexport) int Getvar();
    };
} 

MyWin32ClassTwo.cpp

C++
#include "MyWin32ClassTwo.h"

namespace MyWin32DLL
{
    MyWin32ClassTwo::MyWin32ClassTwo()
    {
        vartwo = 345;
    }

    void MyWin32ClassTwo::Setvar(int val)
    {
        vartwo = val;
    }
 
    int MyWin32ClassTwo::Getvar()
    {
        return vartwo;
    }
}  

Build the project and look for the output DLL in the Debug/Release folder. We have now created our C++ Win32 DLL!

What's the purpose of a DLL if there's no one that uses it, right? So let's create a simple Win32 Console Application that will use our DLL's functionalities.

In Visual Studio, add a new Win32 Console Project as an Empty Project and name it "MyWin32CppApp" and then add a source file named "Main.cpp" just like below.

Add below code to Main.cpp:

Main.cpp

C++
#include<iostream>//for cin, cout and endl
using namespace std;
 
#include "MyWin32ClassOne.h" 
#include "MyWin32ClassTwo.h" 
using namespace MyWin32CppDLL;
 
int main()
{
    cout<<"Hello C++ Win32 DLL"<<endl;
 
    MyWin32ClassOne sc1;
    cout<<"default value of variable from dll : "<<sc1.Getvar()<<endl;
    sc1.Setvar(101);
    cout<<"value of variable from dll : "<<sc1.Getvar()<<endl;
 
    MyWin32ClassTwo sc2;
    cout<<"default value of variable from dll : "<<sc2.Getvar()<<endl;
    sc2.Setvar(200);
    cout<<"value of variable from dll : "<<sc2.Getvar()<<endl;
 
    cin.get();//pause console to see the message

    return 0;
}

Before we can build our application correctly, we need to add a reference to our DLL. Right click the Application project and select "Properties" to open its property page.

First, navigate to "C/C++ > General > Additional Include Directories" then assign the full path where the header files of the DLL are located. This will tell the compiler to locate MyWin32ClassOne.h and MyWin32ClassTwo.h in this location. Click OK.

Second, right click Application project and select "References...". Click "Add New References" and select the DLL project we previously created. Click OK. Finally, build the Solution as Release. Navigate to "Release" folder and launch MyWin32CppApp.exe.

Points of Interest

When we add the path to the header files in our application project, we are just telling the compiler to locate the header files we are using from that location. But when we add reference to our DLL project from our application project, we are basically telling the Linker to link the header files of the actual implementation of our Win32 DLL. 

Advanced points to ponder: 

  •  C++ DLL built from different compilers may not be consumed by a C++ Application/other C++ DLL directly because C++ compilers have different "name mangling" specifications. *This is why we need to compile the source of a C++ DLL project along with our C++ application to ensure they are built using the same compiler.
  • For a C++ DLL to be imported in a C application, global functions.
  • In .NET C#, you can only "DllImport" or "PInvoke" globally exported functions from a C++ DLL.

Hope this helps.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Philippines Philippines
Raw tools of C++ and highly sophisticated C#.Net framework architecture is picture-perfect!

Comments and Discussions

 
QuestionC++ dll on windows Pin
Member 1375317629-Mar-18 2:35
Member 1375317629-Mar-18 2:35 
Questiona suggestion Pin
Southmountain3-Feb-18 9:28
Southmountain3-Feb-18 9:28 
QuestionGood Project type description Pin
Mónica_Cid4-May-17 5:59
Mónica_Cid4-May-17 5:59 
QuestionTypo in Main.CPP file Pin
Member 1226665015-Jan-16 5:58
Member 1226665015-Jan-16 5:58 
QuestionAlmost there Pin
brownpeteg15-Sep-15 1:27
brownpeteg15-Sep-15 1:27 
QuestionPlease include a demo project Pin
Franc Morales1-Apr-14 7:48
Franc Morales1-Apr-14 7:48 
GeneralMy vote of 3 Pin
sandeep00773415-Oct-13 23:06
sandeep00773415-Oct-13 23:06 
Questiontypo Pin
Orlando Selenu7-Oct-13 23:31
Orlando Selenu7-Oct-13 23:31 
SuggestionC++ Win32 DLLs are called unmanaged code ..... Pin
LaxmikantYadav3-Oct-13 20:48
LaxmikantYadav3-Oct-13 20:48 
GeneralRe: C++ Win32 DLLs are called unmanaged code ..... Pin
ThatsAlok7-Oct-13 19:23
ThatsAlok7-Oct-13 19:23 
GeneralRe: C++ Win32 DLLs are called unmanaged code ..... Pin
KarstenK11-Aug-14 7:13
mveKarstenK11-Aug-14 7:13 
Questionstrange order of result according to classes definitions Pin
ersi057130-Sep-13 20:09
professionalersi057130-Sep-13 20:09 
QuestionQuestion Pin
Richard MacCutchan26-Sep-13 0:52
mveRichard MacCutchan26-Sep-13 0:52 
AnswerRe: Question Pin
wembikon26-Sep-13 17:05
wembikon26-Sep-13 17:05 
GeneralRe: Question Pin
Richard MacCutchan26-Sep-13 21:27
mveRichard MacCutchan26-Sep-13 21:27 
GeneralMy vote of 5 Pin
aydinsahin19-Sep-13 4:24
aydinsahin19-Sep-13 4:24 
SuggestionPossible "simplification" Pin
pasztorpisti18-Sep-13 5:33
pasztorpisti18-Sep-13 5:33 
GeneralRe: Possible "simplification" Pin
wembikon18-Sep-13 17:39
wembikon18-Sep-13 17:39 
GeneralRe: Possible "simplification" Pin
giulicard22-Sep-13 23:50
giulicard22-Sep-13 23:50 
Ok, it's a possible solution, but it's dependent by the compiler used, i.e., IMHO only the same C++ compiler used to build the DLL can be used to consume it. C++ ABI is not standardized on Windows as is for C. So I suspect that some mechanisms behind the scenes, like virtual function handling or C++ language exception handling, can be implemented very differently between different compilers. For application development under Windows there are (among others) three main compilers which are widespread: MS C++ compiler, GCC MinGW porting and BCC32 (Bor[land]Code[gear][Embarca]Dero, aka BorCodeDero 32 bit C++ Compiler). All three these compilers, AFAIK, uses different approaches to aforementioned mechanism. IMHO, a DLL which has C++ code inside, should be constructed with these problems in mind. So, a DLL should expose all functions as standard C functions, emulating the construction/destruction C++ facility using one or more functions for the construction (if underlying C++ class has overloaded constructors) and a closing function for the destructor. Functions wrapping the constructors should return a handler to pass to wrapped class' methods used to recover the this pointer (the 'this' pointer itself, casted to a void* could be used as handler return value from DLL's opening functions). So, wanting use a such DLL with different compilers, IMHO, it's better to use a classic solution, i.e. a wrapper C function for each method of the underlying class. Also you have to be aware that different memory manager could be in DLL and host application consuming the DLl itself. So it's important that it's only the DLL that creates and releases resources needed for working. Even each DLL function should to wrap C++ code inside a try { } catch( ... ) {} (catch all block) as shouldn't be permitted to C++ exceptions to escape from a DLL.

My $0,02

Regards

Giuliano
GeneralRe: Possible "simplification" Pin
pasztorpisti23-Sep-13 0:24
pasztorpisti23-Sep-13 0:24 
GeneralRe: Possible "simplification" Pin
giulicard23-Sep-13 3:52
giulicard23-Sep-13 3:52 
GeneralRe: Possible "simplification" Pin
pasztorpisti23-Sep-13 4:32
pasztorpisti23-Sep-13 4:32 
GeneralRe: Possible "simplification" Pin
giulicard23-Sep-13 5:10
giulicard23-Sep-13 5:10 
GeneralRe: Possible "simplification" Pin
pasztorpisti23-Sep-13 5:22
pasztorpisti23-Sep-13 5:22 
GeneralRe: Possible "simplification" Pin
John Bandela27-Sep-13 4:25
John Bandela27-Sep-13 4:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.