Welcome to Code Diaries


Welcome to the one place where you can probably find any kind of C++ or Java Tutorial. From templates and database pools to beans and JNDI, for unix and Windows. We have it all. Cant find what you need? Take a look at the tutorial trail Tutorial Trail. All the examples are categorised by technology







Search Code Diaries and sister sites Google

Simple Windows C++ DLL Example with Implicit and Explicit Calls

Aim
The aim of this tutorial is to build a simple DLL using the command line VIsual C++ compiler and then create two small programs that will call this implicitly by linking with the lib file and explicitly using LoadLibrary and GetProcAddress.

Assumptions
This article assumes that you have a compatible version of Visual C++ installed and you have run vcvars32. The file is called MyHook because it will be used later as a windows keyboard hook dll.

Versions used in this example
Sofware/Component
Image
Windows XP SP2
N/A
Visual C++ 2008 Express Edition
N/A
Links to these files can be found here


CPPDLLExample
_|_MyHook.cpp
_|_MyHook.h
_|_MyHook.def
_|_CPPDllImplicit.cpp
_|_CPPDllExplicit.cpp

The dll requires 3 files. Source file, header file and a definitions file. This def file is required to expose the functions for explicit linking only

Create the DLL
  1. Create the source file and save it as MyHook.h
     1. #ifndef MYHOOK_H
     2. #define MYHOOK_H
     3. 
     4. #ifdef MYHOOK_DLLEXPORT
     5. #define MYHOOK_API __declspec(dllexport)
     6. #else
     7. #define MYHOOK_API
     8. #endif
     9. 
    10. MYHOOK_API int AddNumbers(int, int);
    11. MYHOOK_API int GetMessage(char*, int);
    12. 
    13. #endif
    Hide line numbers

  2. Create the source file and save it as MyHook.cpp
     1. #include "MyHook.h"
     2. #include <string.h>
     3. 
     4. MYHOOK_API int AddNumbers(int x, int y){
     5.     return x + y;
     6. }
     7. MYHOOK_API int GetMessage(char* x, int length){
     8.     if(length>32){
     9.         strcpy(x, "hello from dll");
    10.         return 0;
    11.     }
    12.     else
    13.         return -1;
    14. }
    Hide line numbers

  3. Finally create the definitions file and save it as MyHook.def
     1. ; MyHook.def : Declares the module parameters for the DLL.
     2. 
     3. LIBRARY      "myhook"
     4. DESCRIPTION  "MyHook Windows Dynamic Link Library"
     5. 
     6. EXPORTS
     7.     ; Explicit exports can go here
     8.     AddNumbers
     9.     GetMessage
    10.     
    11. SECTIONS
    12.     ; Pragma sections
    Hide line numbers

  4. Build the library on the command line

    ...CPPDLLExample>cl -o myhook.dll myHook.cpp /D MYHOOK_DLLEXPORT /link /DLL /DEF:"MyHook.def"


Write and Compile Implicit caller
  1. Write implicit compiler and save it as CallDLLImplicit.cpp
     1. #include <iostream>
     2. #include "MyHook.h"
     3. 
     4. using namespace std;
     5. int main(){
     6. 
     7.     char msg[64];
     8.     cout << AddNumbers(5,10) << endl;
     9.     GetMessage(msg, 64);
    10.     cout << msg << endl;
    11. 
    12. }
    Hide line numbers

  2. Build the program using,

    ...CPPDLLExample>cl CallDllImplicit.cpp MyHook.lib

Write and compile the explicit client
  1. Write the explicit caller and save it as CallDllExplicit.cpp
     1. #include <iostream>
     2. #include <windows.h>
     3. 
     4. typedef int(*pAddNumbers)(int,int);
     5. typedef int(*pGetMessage)(char*,int);
     6. 
     7. using namespace std;
     8. int main(){
     9. 
    10.     HINSTANCE hInstance;
    11.     
    12.     if(!(hInstance=LoadLibrary("myhook.dll"))){
    13.         cout << "could not load library" << endl;
    14.         goto FINISH;
    15.     }
    16. 
    17.     pAddNumbers padd = (pAddNumbers)GetProcAddress(hInstance, "AddNumbers");
    18.     pGetMessage pget = (pGetMessage)GetProcAddress(hInstance, "GetMessage");
    19. 
    20.     if(!padd || !pget){
    21.         cout << "could no load functions" << endl;
    22.         goto FINISH;
    23.     }
    24. 
    25.     char msg[64];
    26. 
    27.     cout << padd(20,35) << endl;
    28.     pget(msg, 64);
    29.     cout << msg << endl;
    30. 
    31. FINISH:
    32.     cout<<"finished"<<endl;
    33. }
    Hide line numbers

  2. Now cd out to the workingdirectory build it

    ...CPPDLLExample>cl CallDLLExplicit.cpp


Running the executables
  1. Open a command prompt into your working directory and the executables. You should be able to see the results. Delete the dll and run them again - you should get an error message

Back to the tutorial trail | Home

Double Dispatch and Visitor Pattern Example

Double dispatch is a way to call different (but-related) concrete functions depending on the runtime types of the various objects involved in the call. IT basically replacing static compile time casting with dynamic resolving of calls.

Here is an example of the a double dispatch. Let's say it's a game. You have a wildanimal that attacks types of humans, and a warrior which derives from human. Let us consider a wildanimal attacking a warrior. I strongly suggest running this code for a better understanding.

The problem is on line 60 you have w->attack(h). This leads to static compile time function overloading and you end up selecting the 'Human Attack' at line 44. This leads to a wild animal attacking a human despite the fact that it should be attacking a warrior.

The solution is to have a DD that allows the proper dynamic cast by using the 'this' pointer (line 26). Now when you call h->attackedbywildanimal(w); at line 54 you will get the correct wild animal attacking a warrior instead of a human.

Note that a simpler but far less flexible solution would have been to simply statically cast the pointer at line 50 to be w->attack((warrior*)h);.

Note that to have all the code in a single file I needed class definitions at the top and the wildanimal implementation is actuall at the bottom. Remind me to use java next time!

 1. #include <iostream>
 2. 
 3. using namespace std;
 4. 
 5. class human;
 6. class warrior;
 7. class wildanimal{
 8. public:
 9.     virtual void attack(human*);
10.     virtual void attack(warrior*);
11. };
12. 
13. class human{
14.   public:
15.     virtual void attackedbywildanimal(wildanimal *animal){
16.         animal->attack(this);
17.     }
18.     void GetHealth(){
19.         cout<<"Human health\n";
20.     }
21. };
22. 
23. class warrior : public human{
24. public:
25.     virtual void attackedbywildanimal(wildanimal *animal){
26.         animal->attack(this);
27.     }
28.     void GetHealth(){
29.         cout<<"Warrior health\n";
30.     }
31. };
32. 
33. void wildanimal::attack(human* h){
34.       cout<<"Animal attacks human ";
35.       h->GetHealth();
36. }
37. void wildanimal::attack(warrior* w){
38.       cout<<"Animal attacks warrior ";
39.       w->GetHealth();
40. }
41. 
42. class boar: public wildanimal{
43. public:
44.     void attack(human* h){
45.         cout<<"Boar attacks human ";
46.         h->GetHealth();
47.     }
48.     void attack(warrior* w){
49.         cout<<"Boar attacks warrior ";
50.         w->GetHealth();
51.     }
52. };
53. 
54. int main(int argv, char** argc){
55.   
56.     human * h = new warrior();
57.     wildanimal * w = new boar();
58.   
59.     //Problem
60.     w->attack(h);
61.     
62.     //Double Dispatch solution
63.     h->attackedbywildanimal(w);
64. }
Hide line numbers