HomeC&C++WainTutorialsSamplesTip & TrickTools


And now a quick guide on how to create a windows .dll file, and how to use it.
First we create a headerfile for our .dll, it contains the classes and functions the dll will implement.
It will look like this, it is to be put it into mydll.h:
class Whatever
{
public:
   __declspec(dllexport) Whatever(int aX, int aY);
   __declspec(dllexport) int Get();
private:
   int X, Y;
};
__declspec(dllexport) int DoSomething(int a, int b);
The only strange thing here is the __declspec(dllexport) part, it tells the compiler that the functions are exported from the dll.
Now the source of the dll, stored in mydll.cpp:
#include <windows.h>
#include "mydll.h"
__declspec(dllexport) BOOL
APIENTRY DllMain(HANDLE hModule,
                 DWORD  ul_reason_for_call,
                 LPVOID lpReserved)
{
   switch (ul_reason_for_call)
   {
   case DLL_PROCESS_ATTACH:
   case DLL_THREAD_ATTACH:
   case DLL_THREAD_DETACH:
   case DLL_PROCESS_DETACH:
      break;
   }
   return TRUE;
}

__declspec(dllexport) int DoSomething(int a, int b)
{
   return a*b*2;
}

__declspec(dllexport) Whatever::Whatever(int aX, int aY)
   : X(aX), Y(aY)
{
}

__declspec(dllexport) int Whatever::Get()
{
   return X*Y;
}
The DllMain function is not strictly needed. If included it will be called when the DLL is loaded and unload. It can be used to do one time initialization.

Now we can create the DLL. But first a note on how the user are to use the DLL. One way is to use LoadLibrary and GetProcAddress, but thats an clumsy and insecure way to do it. A better way is to create a library which forms a bridge between the DLL and the user code, this enables the user to use the functions in the DLL as every other functions.
And fortunately the compiler can create this library for us, in some cases as a part of building the DLL in other cases by using a tool.

First gcc, tested with mingw, the following is one line:
g++ -W -Wall -shared -o mydll.dll mydll.cpp
   -Wl,--out-implib=libmydll.a -Wl,--export-all-symbols
   -Wl,--enable-auto-import
This will create mydll.dll and the library libmydll.a
Then VisualC++, tested with version 6.0:
cl /LDd mydll.cpp
This will create both mydll.dll and mydll.lib
Both BorlandC++ and Digital Mars C++ does the job in two steps, first create the DLL and then the library.
BorlandC++:
bcc32 -WD mydll.cpp
implib mydll.lib mydll.dll
And Digital Mars C++:
dmc -mn -WD mydll.cpp kernel32.lib
implib.exe /noi mydll.lib mydll.dll

So let's test if it works, a tiny test program called mytest.cpp:
#include <iostream>
#include <windows.h>
#include "mydll.h"

int main()
{
   Whatever W(3, 4);
   std::cout << W.Get() << std::endl;
   std::cout << DoSomething(2, 4) << std::endl;

   return 0;
}
To build it we have to link with the library, first gcc:
g++ -W -Wall mytest.cpp libmydll.a -o mytest.exe
And VisualC++:
cl /GX mytest.cpp mydll.lib
BorlandC++:
bcc32 mytest.cpp mydll.lib
And Digital Mars C++:
dmc mytest.cpp mydll.lib
In all cases mytest.exe should be build.

I have collected the code and .bat files to build and run it in a zip file.