【问题标题】:Porting callback function from 32 bit to 64 bit将回调函数从 32 位移植到 64 位
【发布时间】:2014-12-05 13:01:18
【问题描述】:

我正在使用 Visual Studio 2008 Professional 进行构建。当我使用 Win32 build 编译时,它编译得很好。

但是当我切换到 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

一些定义/类型定义::

typedef unsigned long DWORD;
#define CALLBACK __stdcall

tapi.h 中的 LINECALLBACK 是这样定义的:

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

在 Windows 上 unsigned long 在 32 位和 64 位平台上是 32 位宽。所以这肯定不是问题。

任何想法为什么?以及如何解决?

这里是代码。

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

所以我的回调定义是错误的!

【问题讨论】:

    标签: c windows 64-bit tapi


    【解决方案1】:

    就参数的声明而言

    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 是第一个声明中的指针和第二个声明中的整数。

    由于 omn 32 位 Windows DWORDs 的大小与可能编译的指针大小相同。

    但在 64 位 Windows 上,指针的大小与 DWORDs 不同。

    【讨论】:

    • True 但 DWORD 和 DWORD_PTR 都是 typedef 为 unsigned long 所以它们应该是等价的。刚刚试了一下,就解决了!
    • 也许,也许不是。显然不是在这种情况下。您确定 DWORD_PTR 不是类型定义为 DWORD * 吗?如果是这种情况,它将是 64 位类型,而 DWORD 可能是 32 位类型。
    • 啊,智能给了我错误的信息 - DWORD_PTR 的 typedef 实际上是: typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;所以这就解释了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 2011-01-31
    • 2020-10-28
    • 2011-03-11
    • 2014-08-13
    • 2010-12-12
    • 2015-06-16
    相关资源
    最近更新 更多