Search code examples
cwindows64-bittapi

Porting callback function from 32 bit to 64 bit


I am building using Visual Studio 2008 Professional. When I compile using Win32 build it compiles just fine.

But when I switch to x64 then I get this compilation error:

error C2664: 'lineInitializeExA' : cannot convert parameter 3 from 'void (__cdecl *)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD)' to 'LINECALLBACK'
    None of the functions with this name in scope match the target type

Some of the defines/typedefs::

typedef unsigned long DWORD;
#define CALLBACK __stdcall

And LINECALLBACK in tapi.h is defined like this:

typedef void (CALLBACK * LINECALLBACK)(
DWORD               hDevice,
DWORD               dwMessage,
DWORD_PTR           dwInstance,
DWORD_PTR           dwParam1,
DWORD_PTR           dwParam2,
DWORD_PTR           dwParam3
);

On Windows unsigned long is 32 bits wide on 32 and 64 bit platform. So surely that isn't a problem.

Any ideas why? and how to fix?

Here is the code.

#include <tapi.h>  // Windows tapi API
#include <stdio.h>

/*  
     I know it says tapi32.lib but I believe that is just old naming - 
     don't think 32 bit specific.  and in any case don't get to linking phase
*/
#pragma comment(lib,"tapi32.lib")  

void CALLBACK my_callback(DWORD dwDevice, 
                              DWORD nMsg, 
                              DWORD dwCallbackInstance, 
                              DWORD dwParam1, 
                              DWORD dwParam2, 
                              DWORD dwParam3) {
       printf("my_callback called\n");
}

int main() {

   LONG result = -1;
   DWORD dwAPIInit = 0x00020002;   
   HLINEAPP    happ;             // application handle
   DWORD       numlines;         // Number of line devices in system.
   result = lineInitializeEx (&happ, GetModuleHandle(0),
      my_callback, "TAPITEST", &numlines, &dwAPIInit, 0); 

   return 0;
}

**** EDIT. Not sure why, but I was seeing DWORD_PTR as:

typedef unsigned long DWORD_PTR;

But on checking is using:

typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;

So my callback definition is wrong!


Solution

  • In terms of the arguments' declarations this

    void (CALLBACK * LINECALLBACK)(
      DWORD               hDevice,
      DWORD               dwMessage,
      DWORD_PTR           dwInstance,
      DWORD_PTR           dwParam1,
      DWORD_PTR           dwParam2,
      DWORD_PTR           dwParam3
    );
    

    isn't the same as this:

    void CALLBACK my_callback(
      DWORD dwDevice, 
      DWORD nMsg, 
      DWORD dwCallbackInstance, 
      DWORD dwParam1, 
      DWORD dwParam2, 
      DWORD dwParam3
    ):
    

    Arguments 3 to 6 are pointers in the 1st decarations and integers in the 2nd.

    As omn 32bit Windows DWORDs have the same size as pointers this might compile.

    On 64bits-Windows however pointers have a different size from DWORDs.