0

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!

Angus Comber
  • 9,316
  • 14
  • 59
  • 107

1 Answers1

2

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.

alk
  • 69,737
  • 10
  • 105
  • 255
  • True but both DWORD and DWORD_PTR are typedef'd to unsigned long so they should be equivalent. Just tried that and that fixes! – Angus Comber Oct 10 '14 at 11:25
  • 2
    Maybe, maybe not. Apparently it's not in this case. Are you certain that DWORD_PTR isn't typedefed to DWORD *? If that's the case it would be a 64 bit type, while DWORD could be a 32 bit type. – Clearer Oct 10 '14 at 11:27
  • 1
    Ahhh the intellisence was giving me wrong information - typedef for DWORD_PTR is actually: typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; So that explains. Thank you. – Angus Comber Oct 10 '14 at 11:29