Virtual Developer Workshop: Containerized Development with Docker

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:

#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);

// Comment out the line below, if you want STDCALL 
// for the VB-Example.

  #include "DLL_Callback.h"
  #include "DLL_Callback_StdCall.h"

// 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.
// ...
  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, 

// 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:



// 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);

#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
// Call the function of the DLL, which reads DB-Info 
// or something else.

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


Download source including VC/VB demo project - 10 KB


  • helpful article

    Posted by ricky_cpp on 12/10/2008 03:11pm

    Thanks..this article has helped in undestanding concept of callbacks in windows :-)

  • DLL_Callback: Sample for asyncronous inner-process operations.

    Posted by Legacy on 10/21/2002 07:00am

    Originally posted by: Suman Bhattacharya

    This is working fine when running from VB IDE.But it fails after creating exe.It raises an error like "Unable to read from memory".I am doing a project which requires this sort of callback operation. This is an ergent requriement.Pls help me.

  • VB Crashing (Only code chg i was __stdcall) help!

    Posted by Legacy on 08/08/2002 07:00am

    Originally posted by: Mr Unlucky

    It runs and returns the value and the message box appears with the value then Crash! vb completely crashes. Does anyone know why?

    please help thanks.

    VC6 No Service Pack / SP5
    VB6 No Service Pack / SP5

  • callback

    Posted by Legacy on 08/02/2002 07:00am

    Originally posted by: St.Daniel

    i realy dont get it

  • Thread not need ..

    Posted by Legacy on 03/30/2002 08:00am

    Originally posted by: krkim

    The Main Program is holding until the GetData() thread function routine to be end,
    while (iWait) {}; cause this probelm..
    so,thread routine is not meaning.

  • Not a good idea ...

    Posted by Legacy on 03/28/2002 08:00am

    Originally posted by: Robert Simpson

    I highly recommend NOT using this method with VB.

    The callback function is executed from a different thread than the thread that called GetDBData(), and no marshaling is done because this code runs in the absence of COM. VB is designed around COM, and VB's behavior will be erratic at best. Depending on what is done in the callback routine, your VB app may crash hard. Do NOT call any methods on any COM classes (in VB, all apps are COM classes, even the private ones), and take care not to do anything involving COM in the callback. It may work, but it breaks the fundamental rules of COM and is a huge no-no, especially if you want a stable, reliable application.

    Also ... The DoTheWork() function is declared as:

    DWORD DoTheWork(LPVOID lpParameter)

    This is incorrect. It should be declared as:

    DWORD WINAPI DoTheWork(LPVOID lpParameter)

    ThreadProc()'s require the entry point to be _stdcall.

    Robert Simpson
    Programmer at Large
    Black Castle Software, LLC

  • It's useful,but...

    Posted by Legacy on 06/05/2001 07:00am

    Originally posted by: haopf

    This method is useful to me,but how can i pass a pointer
    of buffer in vc++ to vb call back function? If i use a int*
    pointer parameter,vb can't read data form it.

  • New bie!?

    Posted by Legacy on 05/12/2001 07:00am

    Originally posted by: Saad

    Funny I don't see what the big deal is about this crap ?
    Good Luck fella!

  • Welcome!

    Posted by Legacy on 05/08/2001 07:00am

    Originally posted by: Sergey

    At least one Programmer finally realized the life is much easier without COM/COM+/DCOM/.NET

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date