2014-10-10 4 views
0

Я использую Visual Studio 2008 Professional. Когда я компилирую с помощью сборки Win32, она компилируется просто отлично.Передача функции обратного вызова от 32 до 64 бит

Но при переходе на x64, то я получаю эту ошибку компиляции:

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 

Некоторые из DEFINES/определений типов ::

typedef unsigned long DWORD; 
#define CALLBACK __stdcall 

И LINECALLBACK в tapi.h определяется следующим образом:

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

В Windows без знака длина составляет 32 бита на 32 и 64-битной платформе. Так что, конечно, это не проблема.

Любые идеи, почему? и как исправить?

Вот код.

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

**** ИЗМЕНИТЬ. Не знаю, почему, но я видел, как DWORD_PTR:

typedef unsigned long DWORD_PTR; 

Но на проверку использует:

typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; 

Так что мое определение обратного вызова не так!

ответ

2

С точки зрения деклараций аргументов это

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

не то же самое, как это:

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

Аргументы 3 до 6 являются указателями на 1-ом decarations и целых чисел в 2-ом.

As omn 32bit Windows DWORD s имеют тот же размер, что и указатели, которые могли бы скомпилировать.

На 64-битных окнах, однако указатели имеют разный размер от DWORD.

+0

Правда, но оба DWORD и DWORD_PTR являются typedef'd для unsigned long, поэтому они должны быть эквивалентными. Просто попробовал это и все исправления! –

+2

Возможно, может и нет. По-видимому, это не так. Вы уверены, что DWORD_PTR не перенаправлен на DWORD *? Если это так, это будет 64-битный тип, тогда как DWORD может быть 32-битным типом. – Clearer

+1

Ahhh the intellisence давал мне неправильную информацию - typedef для DWORD_PTR на самом деле: typedef ULONG_PTR DWORD_PTR, * PDWORD_PTR; Так что это объясняет. Спасибо. –

Смежные вопросы