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