Environment: VC6 SP3, VB6 SP3
This sample demonstrates the use of asyncronous inner-process operations.
In this case we have an app that wants to get data from a DB,
which could take a undefined long amount of time.
The app wants to do other work while waiting for the result of the DB-Call.
It calls the “GetDBData()”-function, which returns immediately.
After the DLL-function has done its work, it notifies the caller app
via the CALLBACK-function “DataReadNotify()”.
A VB sample which uses this DLL with VB can be found in the “VB_Sample”-Path.
Library Source:
DLL_Callback.h
#ifndef _DLL_CALLBACK_
#define _DLL_CALLBACK_// All declarations which are needed resides in “windows.h”
#include <windows.h>// Placeholder for function-export macros
#define LIBRARY_EXPORT __declspec(dllexport) __cdecl// Function Declarations for Static Export
extern “C” {
long LIBRARY_EXPORT GetDBData(void);
long LIBRARY_EXPORT SetCallbackProcAddr(long);
}// Function Declaration for Callback function
// of the Calling App
typedef void (* TDataReadNotify)(long);#endif
DLL_Callback.cpp
// Comment out the line below, if you want STDCALL
// for the VB-Example.
#define CDECL_CALLING_CONVENTION#ifdef CDECL_CALLING_CONVENTION
#include “DLL_Callback.h”
#else
#include “DLL_Callback_StdCall.h”
#endif// Vars for Imported Functions
TDataReadNotify DataReadNotify;
HANDLE hThread;
DWORD pThreadId;DWORD DoTheWork(LPVOID lpParameter)
{
long lDBData;// Doing stuff that takes 5 sec., i.e. reading DB Data.
// …
Sleep(5000);
lDBData = 123;
// …// Notify the caller app via CB-function.
if (DataReadNotify != NULL) DataReadNotify(lDBData);return 0;
};long LIBRARY_EXPORT GetDBData(void)
{
long lProcAdr;// Get ProcAddress for Thread-Func and create/run the thread.
lProcAdr = (long)(&DoTheWork);
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)lProcAdr,
NULL,
0,
&pThreadId);// Return to caller app.
return 0;
};long LIBRARY_EXPORT SetCallbackProcAddr(long lProcAddress)
{
long Result = 0;// Set the Proc-Address for the notify-func of
// the caller app.
DataReadNotify = (TDataReadNotify)lProcAddress;if (DataReadNotify != NULL) Result = 1;
return Result;
};
C++ Sample Source:
Callback_Sample.h
#ifndef _CALLBACK_SAMPLE_
#define _CALLBACK_SAMPLE_// All declarations which are needed resides
// in “windows.h”
#include <windows.h>// Placeholder for function-import macros
#define LIBRARY_IMPORT __declspec(dllimport) __cdecl// Function Declarations for Static
// Import (aka “Implicied Linking”)
// This requires the Output-LIB of the DLL_Callback Library.
extern “C” {
int LIBRARY_IMPORT GetDBData(void);
int LIBRARY_IMPORT SetCallbackProcAddr(long);
}#endif
Callback_Sample.cpp
#include “Callback_Sample.h”int iWait = 1;
char sDBData[11];
char sMessage[64];void DataReadNotify(long lDBData)
{
_ltoa(lDBData, sDBData, 10);
strcpy(sMessage, “DBData from DLL is: “);
strcat(sMessage, sDBData);
::MessageBox(0, sMessage,
“Sample App”, MB_OK + MB_ICONINFORMATION);
// Set Wait to 0, so that WinMain can go further.
iWait = 0;
};int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
long lProcAdr;// Get Address-Pointer of the CB-function
lProcAdr = (long)(&DataReadNotify);
// Send Address-Pointer Information to the DLL
SetCallbackProcAddr(lProcAdr);
// Call the function of the DLL, which reads DB-Info
// or something else.
GetDBData();// Do other work while the DLL reads the DBData
// …
// I.e.: Show a splash-screen, write values to an
// INI-File or whatever
// …// if the DLL-function is still busy, loop until
// the DLL notifies via the CALLBACK-function “DataReadNotify()”.
while (iWait) {};return 0;
};