Click here to Skip to main content
15,868,002 members
Articles / Desktop Programming / Win32

A Super Easy DLL Made in VC++ IDE, especially for First Time Tasters

Rate me:
Please Sign up or sign in to vote.
4.71/5 (24 votes)
8 Sep 2017CPOL6 min read 21K   237   22   10
Super easy DLL in VC++ IDE
This beginner article might trigger you to open your Visual Studio's Visual C++ IDE for the first time and build a usable DLL out of it, especially if you never opened it before you were scared of its complexity.

Introduction

Just bravely open your Visual C++ IDE (mine is in VS2013), punch several lines of C code (not even C++), make a super easy usable DLL and test it in a little C# app.

Background

If you have been a "business application developer" for a long time (decades?), you probably already built up a sense on not to touch "low level" code.

"low level code is for building the OS, device drivers, DB engines, 3D simulations, real time weapon controllers whatsoever..."

"I can use Java, VB, C# or even script to do everything, as long as there is a wrapper class giving me access to lower level functions".

Those are very common thoughts.

Sometimes, your curiosity does pass your anxiety and fright. But no matter how hard you search, any VC++ examples, even for beginners, will drag you into new jargon worlds: Win32 APIs, .H (header) file, MFC, ATL, Message pump, pointer of pointer (**ppMyVar, what the hell!), COM+, STA, MTA... This is one main reason stopping lots of you even bother to open the VC++ IDE.

In this article and the example code, we will never ever touch those buzzwords, "super easy", I mean it pal! Let's start now.

Using the Code

The code is very simple. I highly recommend you NOT to copy/paste. I suggest you start the IDE, create the solution and file, punch the code line by line all by yourself, manually. This way, you will have a deeper feeling about it (and enjoy it hopefully).

Here are the steps:

  1. Open the VS (mine is VS2013, other version should be very similar). Create a new Visual C++ project. Follow my red marks below (use your own file path, but name the project as SuperEasyDLL):

    Image 1

  2. In the newly created project structure, add a new item as below:

    Image 2

  3. The new item is a C++ File (.cpp). Just follow my highlighted text:

    Image 3

  4. Now let's punch several lines here:

    Image 4

    (Although I recommend you to punch code yourself, but still, just in case you're a copy/paste maniac like myself ;-)

    C++
    int iMySuperEasyOutput;
    extern "C" __declspec(dllexport) void AddingFifty(int iInput);
    extern "C" __declspec(dllexport) int GetMySuperEasyOutput();
    
    void AddingFifty(int iInput)
    {
       iMySuperEasyOutput = iInput + 50;
    }
    
    int GetMySuperEasyOutput()
    {
       return iMySuperEasyOutput;
    }

    As you can see above, no class, no construction, no struct, no Header #include, no nothing but pure basic code. All it does is very simple: Exposing 2 functions. One is to add 50 to input integer, the other is to output the result.

    Yes. Those __declspec(dllexport) keywords are for exporting the functions. You have to guarantee that exported function name and parameter(s) are exactly the same as you actually implemented in the code.

    See? I did try hard not to use jargons.

  5. Make sure SuperEasyDLL is compiled as "DLL", not "EXE". To do that, right click the project, go to properties, and pick "DLL" (as highlighted below):

    Image 5

    Image 6

  6. Build the project, you can see your SuperEasyDLL.dll in the debug folder.

    Image 7

  7. Now let's create the C# winform test project. Name it "SuperEasyDLLWinform". One dummy form, one dummy button. Don't even bother to change the default name. Punch the three pieces of red circled code as below, because those three pieces are not generated by IDE.

    Image 8

    (For your convenience, three pieces are here.)

    C#
    using System.Runtime.InteropServices;
    C#
    [DllImport("SuperEasyDLL.dll")] 
    public static extern int GetMySuperEasyOutput(); 
    [DllImport("SuperEasyDLL.dll", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void AddingFifty(int iTestInput);
    C#
    //input is 50
    AddingFifty(50);
    int iResult = GetMySuperEasyOutput();
                
    //output is 100
    MessageBox.Show(iResult.ToString());

    As you can see now, in our dummy winform app, we are using DLLImport keywords which obviously are trying to use the exported functions we built in DLL.

  8. Make sure winform app EXE can find our DLL easily. Just copy SuperEasyDLL.dll from step(6) to winform debug folder (where the SuperEasyDLLWinform.exe sits).

    Image 9

  9. Beautiful! It's so smart by knowing how to add 50!

    Image 10

Follow the above 9 steps in several minutes, and you are done your 1st VC++ IDE project.

Points of Interest

  1. Is the VC++ code punched above real C++? You might doubt. No and Yes. It doesn't use any C++ features, those super duper cool OO stuff right? No. I choose not to use any of those in this example. "mean and lean", that's what I strive for. But you know what, I heard some pundits said "C" is a subset of "C++", and lots of people agree. So in this perspective, the above code is sort of C++.
  2. The DLL we built could also be called "unmanaged DLL", "native DLL". It means that it doesn't have any .NET framework involved (automatic memory/object gabage collection for example). It also doesn't have any MFC, ATL, COM+ involved. So I call it pure Win32 DLL.
  3. .NET C# app calling unmanaged DLL/native DLL has a specific terminology: P/Invoke (platform invoke). If you are interested, you can find tons of information on it. To me, I just call it DllImport method, just for myself.
    The above POIs are already good enough for this beginner article. Below, I'm going to hit a couple of "beginner+" points, if it's too much for you, please skip...
  4. Remember in our code (both in C# and VC++), you see this:
    C#
    extern "C"

    This is to tell the compiler that, when it compiles the code, the function behind the descriptor should use C standard naming mangling. What is naming mangling? You gulped (because I did that LOL).

    Basically, any function names in IDE are human readable friendly (because we named them of course!). But the compiler will compile them differently. C++ has a standard, C has another. So to keep things simple (C# calling native C DLL), we tell the VS IDE to use C standard naming mangling for both projects.

    To see the compiled mangled name, you first open Developer Command Prompt. It's just a DOS command line under VS environment.

    Image 11

    in the DOS prompt screen, type the command:

    dumpin /exports "C:\data\projtest\SuperEasyDLL\Debug\SuperEasyDLL.dll" (change your path accordingly).

    Red marked exported name with the extern "C" naming mangling.

    Image 12

    Red marked exported name without the extern "C" naming mangling.

    Image 13

  5. In our little Winform C# code, you can see this:
    C#
    [DllImport("SuperEasyDLL.dll", CallingConvention = CallingConvention.Cdecl)]

    The "CallingConvention.Cdecl" is to tell the compiler that this function call is going to clean the stack from C# client side. I guess the compiler will add some boilerplate binary code around it once compiled. I'm not an expert and I don't really know. What I really know is without this, the app will pop error complaining about some sort of stack issues.

People always say that from 0 to 1 is a big step, but we are just from 0 to 0.1.

But hey, a tiny step is still a step moving forward.

Hope you get your hands dirty and like it just as I did.

My next beginner article for anyone who wants to know a little more on VC++ is here:

History

  • 8th September, 2017: Initial version

License

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


Written By
Software Developer
Canada Canada
Yet another jack-of-all-trades programmer?


Comments and Discussions

 
Questioncalling it from c++ consol Pin
Khayralla28-Sep-17 10:35
Khayralla28-Sep-17 10:35 
AnswerRe: calling it from c++ consol Pin
simonp_ca28-Sep-17 14:21
simonp_ca28-Sep-17 14:21 
PraiseCheers Pin
Mikaels133719-Sep-17 1:02
professionalMikaels133719-Sep-17 1:02 
SuggestionRefactoring ;-) Pin
DCUtility13-Sep-17 15:20
professionalDCUtility13-Sep-17 15:20 
GeneralRe: Refactoring ;-) Pin
simonp_ca13-Sep-17 15:28
simonp_ca13-Sep-17 15:28 
GeneralMy vote of 1 Pin
Paolo Botti11-Sep-17 19:58
professionalPaolo Botti11-Sep-17 19:58 
PraiseMy vote of 5! Pin
jediYL11-Sep-17 19:44
professionaljediYL11-Sep-17 19:44 
GeneralRe: My vote of 5! Pin
simonp_ca12-Sep-17 12:49
simonp_ca12-Sep-17 12:49 
Suggestion[My vote of 1] huh? Pin
Philip Liebscher11-Sep-17 16:33
Philip Liebscher11-Sep-17 16:33 
GeneralRe: [My vote of 1] huh? Pin
simonp_ca11-Sep-17 16:59
simonp_ca11-Sep-17 16:59 

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.