Content of a callback function

The processing that occurs in the callback function is entirely up to you. This section illustrates a simple way of handling it.

UserData buffer

In this example, the UserData buffer is a structure with a field whose value points to the actual message buffer. Other fields keep track of the message buffer's contents as it is filled:

typedef struct ORCA_UserDataInfo {
   LPBYTE lpszBuffer;     // Buffer to store data
   DWORD dwCallCount;    // # of messages in buffer 
   DWORD dwBufferSize;   // size of buffer 
   DWORD dwBufferOffset; // current offset in buffer 
} ORCA_USERDATAINFO, FAR *PORCA_USERDATAINFO;

Calling program

In the calling program, the UserDataInfo structure is initialized.

The calling program does not know how much room will be required for messages, so it allocates 60000 bytes (an arbitrary size). If you are gathering link errors, it's probably enough. It might not be enough if you wanted directory information for a large library:

ORCA_USERDATAINFO UserDataBuffer;
PORCA_USERDATAINFO lpUserDataBuffer;
 
lpUserDataBuffer = &UserDataBuffer;
lpUserDataBuffer->dwCallCount = 0;
lpUserDataBuffer->dwBufferOffset = 0;
lpUserDataBuffer->dwBufferSize = 60000;
lpUserDataBuffer->lpszBuffer = 
  (LPTSTR)malloc((size_t)lpUserDataBuffer-> 
     dwBufferSize);
memset(lpUserDataBuffer->lpszBuffer, 
      0x00,(size_t)lpUserDataBuffer->dwBufferSize);

Define function pointer

The calling program defines a function pointer to the callback function that it passes to the ORCA function:

PBORCA_LINKPROC fpLinkProc; 
fpLinkProc = (PBORCA_LINKPROC)LinkErrors;

Call ORCA

The calling program calls the ORCA function, passing the callback function pointer and the UserData buffer pointer. This example calls PBORCA_ExecutableCreate, whose callback type is PBORCA_LNKPROC:

rtn = PBORCA_ExecutableCreate(..., (PBORCA_LNKPROC) 
fpLinkProc, lpUserDataBuffer);

Process results

Finally, the calling program can process or display information that the callback function stored in the UserData buffer.

Free allocated memory

If your UserData structure allocates memory, free the allocated memory:

free( lpUserDataBuffer->lpszBuffer )

Callback program

The callback program receives a structure with the current error or information and stores the information in the message buffer pointed to by lpszBuffer in the UserData buffer. It also manages the pointers stored in the UserData buffer.

Simple callback

A simple callback might do the following:

  • Keep count of the number of times it is called

  • Store messages and reallocate buffer if it overflows

This code implements a callback called LinkErrors for PBORCA_ExecutableCreate:

void CALLBACK LinkErrors(PPBORCA_LINKERR lpLinkError, 
      LPVOID lpUserData) 
{
   PORCA_USERDATAINFO lpData;   
   LPBYTE lpCurrByte;
   LPTSTR lpCurrentPtr;
   int iNeededSize;
   lpData = (PORCA_USERDATAINFO) lpUserData;
 
   // Keep track of number of link errors
   lpData->dwCallCount++;
 
   // Is buffer already full?
   if (lpData->dwBufferOffset==lpData->dwBufferSize)
   return;
 
   // How long is the new message? 
   // Message length plus carriage rtn and newline
   iNeededSize = 
      (_tcslen(lpLinkError->lpszMessageText) + 2)* 
          sizeof(TCHAR);
    // Reallocate buffer if necessary
   if ((lpData->dwBufferOffset + iNeededSize) > 
      lpData->dwBufferSize)
   {
      LPVOID lpNewBlock;
      DWORD  dwNewSize;
      dwNewSize = lpData->dwBufferSize * 2; 
      lpNewBlock = realloc(lpData->lpszBuffer,
         (size_t)dwNewSize);
      if (lpNewBlock)
      {
         lpData->lpszBuffer = (LPTSTR) lpNewBlock;
         lpData->dwBufferSize = dwNewSize;
      }
      else
         return;
   }
   
   // Set pointer for copying message to buffer
     lpCurrentPtr = lpData->lpszBuffer 
        + lpData->dwBufferOffset;   
      lpCurrString = (LPTSTR) lpCurrByte;
 
  // Copy link error message, CR, and LF to buffer. 
  _tcscpy(lpCurrentPtr, lpLinkError->lpszMessageText);
  _tcscat(lpCurrentPtr, _TEXT("\r\n"));
  lpData->dwBufferOffset += iNeededSize;
  return;
}