# How To Create A .Dll in Visual C++ Express 2008



## -Fabez-

Is it possible to create .Dll's in Visual C++ Express 2008 and if so how ? Also any help on how to code a .Dll would be much appreciated. Thanks -Fabez-


----------



## mt2002

Of course 

Project Properties->Configuration Properties->General (Usually automatically opens as soon as you open project properties)

Then change *configuration type* to *Dynamic Library (*.dll)*. Rebuild and the module will be output as a dll.

Working with *.dll's are a little different though. They do not require an entry point (If there is one, it should be DLLMain()). And any symbolic information that you want to export from the dll (perhaps to provide the dll an interface) requires *__declspec (dllexport)* and be imported by the program using the dll (*__declspec (dllimport)*). I can post an example if needed.


----------



## -Fabez-

Thanks for the information  An example would be greatly appreciated, preferably a minimal example that works with vitually all compilers like Visual C++ and Dev C++ for example. Thanks -Fabez-


----------



## mt2002

I cant show an example that will work on all compilers as there is no portable way. Dll linkage is not defined by the standard thus there is no possible way without using compiler extensions.

I have only done it using Visual C++ 6, 2005, and 2008 thus can only post an example in that compiler.


----------



## -Fabez-

Okay then, can you post a Visual C++ example please. Thanks -Fabez-


----------



## mt2002

*Creating the DLL*

Create a new project and a new source and header file for it. Call them *dllheader.h* and *main.cpp* for now. Go to your project properties and set it to a DLL project (See my previous post).

This is a small tutorial-post that will show you how to create the DLL and use it in another program. Keep in mind, however, that it does not show you how to dynamically load and work with DLLs. For that, you need to look into LoadModule or LoadLibrary routines. Its easy though and will NOT require needing an import library file that this tutorial has. That is, this tutorial-post requires you to set an extra dependency that is statically linked into the project and delay-loads the DLL for simplicity. I can show you how to modify this demo after you get it working to dynamically work with the DLL if you like.

Anyways, on with the show 

Add the following code to *dllheader.h*:



Code:


#ifndef DLLHEADER_H_INCLUDED
#define DLLHEADER_H_INCLUDED

#ifdef DLL_EXPORT
# define EXPORT __declspec (dllexport)
#else
# define EXPORT
#endif

extern EXPORT void foo ();

#endif

foo() is the routine that the DLL will export. However we only want to export it when building the DLL project. Because of this, only the DLL project should define DLL_EXPORT.

Now for *main.cpp* in the DLL's project...



Code:


#define DLL_EXPORT
#include "dllheader.h"
#include <iostream>

EXPORT void foo () {

	std::cout << "This is the DLL!" << std::endl;
}

All this does is export the routine (by defining DLL_EXPORT). The routine simply prints a screen to let you know it is executing.

Thats all. Build the project and it will output two files: A dll and a lib file. The lib file is for import symbols only and still requires the dll to run if you use it. Using the lib file alone will cause an error from Windows that the dll file is missing.

*__declspec is MSVC specific*.

*Test the dll*

Create a new project and create a new source file. Set up the header include paths/library paths (or just copy the lib, dll, and dllheader.h file to the new projects working directory).

Also in this project settings go to *Configuation properties->Linker->Input* and then look for *Delay Loaded DLL*. Enter the path to the DLL you have just created. Also, in *Additional Dependencies* give it the path to the import library (*.lib) file that was created.

Test it like this (Assumes you set the include directory paths to where dllheader is located at) :



Code:


#include <dllheader.h>

int main () {

	foo ();
}

Build the project and test it. If it works, the string printed from the DLL should display.


----------



## Cookiegal

Reopening thread, as requested.


----------



## -Fabez-

Thanks, Cookiegal  After taking the above example and working through it, I have moved onto dynamically loading .Dll's into my C and C++ code. I have been using the following code to export functions from my .Dll.



Code:


extern "C" __declspec(dllexport) void HelloWorld (){
        cout << "Hello World: Dll Style !!";
    }

This approach has been largely successful, eliminating the need for a .Def file as well as no name mangling, however when I attempt to to export the following function, its name becomes mangled, despite the use of the extern command.



Code:


extern "C" __declspec(dllexport) LRESULT CALLBACK  KeyboardProc(int code,
    WPARAM wParam,
    LPARAM lParam){
}

Is there anything I can do to prevent the mangling of the functions name ?


----------



## mt2002

CALLBACK is _stdcall, which will mangle your function names. You will need to either get rid of CALLBACK in your code (defaults to _cdecl) or replace CALLBACK with _cdecl.

i.e., removing CALLBACK should remove the name mangling. Of course, if this routine is called by Windows directly (as a Windows callback method) then there is no easy way without causing more problems.


----------



## -Fabez-

If there is no way of preventing the name mangling, I guess I can live with using [email protected]  After creating my simple hello world .Dll application, I decided to research what else .Dll's could be used for. Msdn indicated that they could be used in global hooks, so I decided to create a program that would take a screen shot of the users screen, when a certain key combination was pressed. However the documentation is unclear, and does not specify which functions have to be placed in the .Dll and which functions have to be placed in the main program. If you could explain which functions go where I would be grateful. I also have a couple of other questions for you 

1. What is the point in name mangling ?

2. I asked how to create a .Dll as I wanted to produce modular code as my applications got bigger, to keep my code more organized. When placing your code in .Dll's is it possible to declare something in one and use it in another, perhaps using extern ?


----------



## mt2002

> 1. What is the point in name mangling ?


Mangling symbolic names in the global namespace to reduce the possibility of the same symbolic name being defined twice (A common linker error comes to mind...)



> 2. I asked how to create a .Dll as I wanted to produce modular code as my applications got bigger, to keep my code more organized. When placing your code in .Dll's is it possible to declare something in one and use it in another, perhaps using extern ?


Yes it is possible in the same way that you described 

The functions can go anywhere, it really does not matter. A DLL is just a standard program with a different extension after all-no different from a regular EXE program.


----------



## IMM

Have you tried clueing the linker in about it, using 
_#pragma comment( linker, "/export:_TheFunc" )_
and declaring the func extern as you are doing?

http://msdn.microsoft.com/en-us/library/7k30y2k5(VS.71).aspx
http://www.microsoft.com/msj/archive/S202B.aspx

Hooks and callbacks -- sigh
I like .def files


----------



## -Fabez-

Mt2002 and IMM, thanks for the information, I will try and alert the linker to the functions I would like to export. But first, I've got to get the program working  All of the functions related to the global hook are in the .Dll and the .Exe calls the main function, which should start the hook. However, no error messages are generated and the hook does not appear to function, as no output file is generated. Is there anything I might have forgotten to add to make it work ?


----------



## mt2002

Im not sure by what it is that you meen by a "global hook", sorry. Assuming I understand your previous post, your main program calls a function from your DLL to "start the hook". I am also having to assume that the function in the DLL is being called properly.

If that is the case, please elaborate what it is that you are trying to do and I may be able to better assist you


----------



## IMM

mt2002 said:


> Im not sure by what it is that you meen by a "global hook"
> ...
> please elaborate what it is that you are trying to do and I may be able to better assist you


I'm with mt2002 on this one -- I'm also in the dark as to what kind of hook this is to be.
Some code from you?
I was guessing along some of these lines
http://www.codeguru.com/cpp/w-p/system/misc/article.php/c5667
Are you using Microsoft's SetWindowsHookEx ?


----------



## -Fabez-

Sorry, I should have added more information. I initially asked how to create .Dll's as they seemed a good way to modularize my code, making it easier to handle, and because most programs seem to use them. After completing the initial examples given to me by Mt2002, I started looking at what else .Dll's could do. My research indicated that they could be used for global hooks, which I though would be usefull for a global hotkey program, however the documentation is unclear as to which functions go where, and my code does not produce any errors or give any output. Below is the code for the program.



Code:


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

using namespace std;


int main(){
    HOOKPROC KeyProc;
    HINSTANCE MyDll;
    HHOOK MyHook;

    MyDll = LoadLibrary("GlobalHotkey.dll");
    if (MyDll == NULL){
        cout << "MyDll: Loading Failed" << endl;
        return -1;
    }

    KeyProc = (HOOKPROC)GetProcAddress(MyDll, "[email protected]");
    if (KeyProc == NULL){
        cout << "KeyProc: Loading Failed" << endl;
        return -1;
    }

    MyHook = SetWindowsHookEx(WH_KEYBOARD,KeyProc,MyDll,0);
    if (MyHook == NULL){
        cout << "KeyProc: Loading Failed" << endl;
        return -1;
    }

    cout << "MyDll is loaded at: " << MyDll << endl;
    cout << "KeyProc is loaded at: " << KeyProc << endl;
    cout << "MyHook: " << MyHook << endl;

    cin.ignore();
}

And this is the code for my .Dll



Code:


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

using namespace std;

fstream KeyInfo;

extern "C" __declspec(dllexport) void MainFunction(){
    cout << "Dll: Main Function" << endl;
}

extern "C" __declspec(dllexport) LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam){

    cout << "Code: " << code << endl;
    cout << "WPARAM: " << wParam << endl;
    cout << "LPARAM: " << lParam << endl;

    KeyInfo.open ("C:\\KeyInfo.txt", fstream::in | fstream::out | fstream::app);
    KeyInfo << "Code: " << code << endl;
    KeyInfo << "WPARAM: " << wParam << endl;
    KeyInfo << "LPARAM: " << lParam << endl;

    return CallNextHookEx(0, code, wParam, lParam);
}

As stated before, the above code does not produce any errors, neither does it produce any output. Can you see anything wrong with the code, or where the functions are ? Thanks -Fabez-


----------



## mt2002

> I started looking at what else .Dll's could do. My research indicated that they could be used for global hooks


.
They can be, yes. The most common method that I have seen and used them for is an extension to the original program. ie, kind of like a plugin library to extend the functionaily of the original program.

To make things simple for now, lets focus on you being able to call the MainFunction function from the DLL. You do not have to use the symbolic name for the function. So, to get the address of MainFunction, just use *GetProcAddress (MyDll, "MainFunction");*

Please let me know if it gets called.


----------



## -Fabez-

Using the following code, the MainFunction executed without any errors.



Code:


FARPROC Something = GetProcAddress(MyDll, "MainFunction");
if (Something == NULL){
    cout << "MainFunction: Loading Failed" << endl;
    return -1;
}
(Something)();

Just a quick question though, what does FARPROC stand for ?


----------



## mt2002

> Just a quick question though, what does FARPROC stand for ?





Code:


typedef int (FAR WINAPI *FARPROC)()

It identifies a function pointer of the form *int (_stdcall *FARPROC) ()* (FAR is defined as either nothing or the *far* keyword on some older compiliers that support far (32 bit linear) pointers, and WINAPI is defined as _stdcall calling convention in most cases.)

In your code, it creates a function pointer, *something* that points to the function from within the loaded DLL to be called.

k, we have verified that MainFunction right now works? If so, we can focus on the other routine. I am still uncertain if that will work, however, as you are using a C++ calling convention but exporting it as a C routine. I'll have to double check that one...


----------



## burnthepc

Just wanted to say, great post mt2002!

I've wondered how it's done


----------



## -Fabez-

Agreed, it certainly helped


----------



## -Fabez-

I have yet another question for you  If I have the string containing a function name, is it possible to execute the function contained in the string ? Also how do I check if I have read or write permissions to a certain area, such as the users My Documents area to create a settings folder and to create and output folder for the screenshots.


----------



## mt2002

-Fabez- said:


> I have yet another question for you  If I have the string containing a function name, is it possible to execute the function contained in the string ?


You can only indirectly call a function by either i) import/export tables or ii) directly via function pointers (GetProcAddress does this by a function name lookup via the tables) If the only information that you have is the function name, then no you cannot do it directly unless you use one of the above methods.



> Also how do I check if I have read or write permissions to a certain area, such as the users My Documents area to create a settings folder and to create and output folder for the screenshots.


This one I am not to sure of...Im sure there is something in the Win32 API for it though. Ill post it if I find anything...


----------

