Introduction
This sample is demostrating how to create an event in a DLL file and afterward how to call this event from a client program. Hope it can help you to understand the DLL event mechanism and CALLBACK term in VC++.
Diagram
Using the code
1. Open VC++, create an "Win32 Dynamic-Link Library" project called "DllEvent".
2. In "Win32 Dynamic-Link Library- Step 1 of 1" dialog, select "A simple DLL project.". And Then, click "Finish".
3. Add a "DllEvent.h" to "Header Files" as below.
#ifdef DLLEVENT_EXPORTS
#undef DLLEVENT_EXPORTS
#define DLLEVENT_EXPORTS __declspec(dllexport)
#else
#define DLLEVENT_EXPORTS __declspec(dllimport)
#endif
typedef void (CALLBACK *EventCallback)();
DLLEVENT_EXPORTS void WINAPI SetEventCallback(EventCallback func);
DLLEVENT_EXPORTS void WINAPI FireEvent();
Note: "DLLEVENT_EXPORTS" has been defined in the Proejct->Settings->C/C++->Preprocessor definitions, otherwise type "#define DLLEVENT_EXPORTS" in the DllEvent.h
4. Add a "DllEvent.def" to "Header Files" as below.
LIBRARY "DllEvent"
EXPORTS
SetEventCallback @1
FireEvent @2
Note: If you don't define this def file, the output functions will look like "?FireEvent@@YGXXZ" and "?SetEventCallback@@YGXP6GXXZ@Z". After adding this def and recompile the project, the output functions will be "SetEventCallback" and "FireEvent". 5. Add the following include statement and functions content to "DllEvent.cpp".
#include "DllEvent.h"
EventCallback OnEvent=NULL;
DLLEVENT_EXPORTS void WINAPI SetEventCallback(EventCallback func)
{
OnEvent = func;
}
DLLEVENT_EXPORTS void WINAPI FireEvent()
{
if (OnEvent)
OnEvent();
}
6. Compile this project and you should see "DllEvent.dll" and "DllEvent.lib" generated under Debug folder.
7. Create a new "MFC AppWizard(exe)" project, enter "CallDllEvent" as project name, and check "Add to current workspace". In the next step, select "Dialog Base" as its type.
8. Open menu "Project->Dependencies". Then, select "CallDllEvent" and check "DllEvent" as its dependency. By doing so, you can debug both "DllEvent" and "CallDllEvent" within the workspace and also it assures the compiling sequence (first compiling DllEvent, then "CallDllEvent").
9. Delete default 2 buttons ("OK", "Cancel") and "Todo...." static text. Then, add a button (ID: "IDC_CallDll" and Caption: "Call Dll").
10. Double-click IDC_CallDll button and add the following content.
void CCallDllEventDlg::OnCalldll()
{
SetEventCallback( HandleEvent );
FireEvent();
}
11. Open "CallDllEventDlg.cpp", enter the following event handler before "void CCallDllEventDlg::OnCalldll()".
void CALLBACK HandleEvent()
{
AfxMessageBox("Get event from Dll!");
}
12. Open menu "Tools->Options->Directories". In that tab, select "Include files" and add the directory where "DllEvent.h" is located . Also, select "Library files" and add the directory where "DllEvent.lib" is located. By doing so, you don't have to copy "DllEvent.h" &"DllEvent.lib" files to folder of "CallDllEvent" project.
13. Open menu "Project->Settings->Link", enter "DllEvent.lib" in the "Object/library modules".
Note: Make sure "CallDllEvent" project is highlighted on the left panel.
14. Open menu "Project->Settings->Post-build step", create a new command as "copy ..\DllEvent\debug\DllEvent.dll debug\". By doing so, you don't need manually copy the "DllEvent.dll" to debug folder of "CallDllEvent" project. When you compile the project, the system will automatically copy this dll file to specified folder. It's very very useful.
Note: "..\" indicates the up folder.
15. Open "CallDllEventDlg.h" file, enter "#include "DllEvent.h"" statement.
16. Open menu "Build->Rebuild All" to build the both projects. You can see both projects will be compiled.
17. Click menu "Build->Execute CallDllEvent.exe". In the dialog, click "Call Dll" button, it will pop up the message box as below.
Summary
In summary, the whole procedure of this case is as below.
OnCalldll -> SetEventCallback -> FireEvent -> OnEvent -> HandleEvent
If you find any mistake, please post it out or email me. Thanks.
History
1. 2008-6-13 Uploaded the original version.
2. 2008-6-14 Added a diagram and adjusted the other 2 figures.