DLL_Callback: Sample for asyncronous inner-process operations.

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;
};


Downloads

Download source including VC/VB demo project – 10 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read