C2664:在 64 位编译时

Posted

技术标签:

【中文标题】C2664:在 64 位编译时【英文标题】:C2664: while compiling in 64bit 【发布时间】:2012-12-06 17:42:14 【问题描述】:

您好,我有一个使用 vs2008 编译的 32 位源代码可以正常工作。现在我正在尝试以 64 位编译相同的源代码。对于这段代码:

if(EnumResourceLanguages(gHResources, RT_STRING, MAKEINTRESOURCE(1),EnumLangProc, 0) && (0 < gNumSupportedLangs))

我收到以下错误:

Error: error C2664: 'EnumResourceLanguagesA' : cannot convert parameter 4 from 'BOOL (__cdecl *)(HMODULE,LPCTSTR,LPCTSTR,WORD,LONG)' to 'ENUMRESLANGPROCA'

有什么办法可以帮我摆脱它吗?

【问题讨论】:

什么是EnumLangProc?错误信息显然与EnumLangProc 有关。如果错误信息引用EnumLangProc,你必须记住发布EnumLangProc的声明。 看起来最后一个参数应该是LONG_PTR而不是LONG。无论哪种方式,请确保 EnumLangProc 的声明与 ENUMRESLANGPROC 匹配 【参考方案1】:

回调的第四个参数定义为LONGEnumResLangProc 期望 LONG_PTR 作为第四个参数。这是代码中的一个错误,但在 32 位中,LONG 的大小与 LONG_PTR(4 个字节)相同,因此可以正常编译。在 64 位中,LONG_PTR 的长度为 8 个字节,因此您会收到错误消息。更改您的回调签名以接受 LONG_PTR 作为第 4 个参数,它将同时编译为 32 位和 64 位。

【讨论】:

@vivek,你应该接受这个答案。就像 icepack 所说,我的观察是正确的,但这个答案解释了实际问题。【参考方案2】:

您的回调使用__cdecl 调用约定。相反,它需要使用__stdcall 调用约定。适当的函数原型是:

BOOL CALLBACK EnumLangProc(HMODULE, LPCTSTR, LPCTSTR, WORD, LONG_PTR);

CALLBACK 本质上是#defined 是__stdcall

【讨论】:

BOOL CALLBACK EnumLangProc(HMODULE hModule, LPCTSTR 类型, LPCTSTR 名称, WORD 语言, LONG userData) 这就是我对 EnumLangProc 的定义 @chris 虽然您的调用约定观察是正确的,但这不是导致此错误的原因 @icepack,我很确定它在过去给我造成了问题,但是是的,我忘记了这个错误只发生在 64 位,这对于 LONG_PTR 的方式是有道理的 @987654328 @d. @icepack,实际上,我的回忆可能是我使用DWORD() 的签名而不是DWORD WINAPI(LPVOID) 进行线程过程,然后稍后更改这两个东西。那会合适。

以上是关于C2664:在 64 位编译时的主要内容,如果未能解决你的问题,请参考以下文章

为啥在进行 64 位操作时编译器会发生变化?

在 Windows 64 中编译 32 位应用程序时未解析的外部符号

VC++ LNK2001:仅在 64 位编译时无法解析外部符号

在 Ubuntu 中在 32 位上交叉编译 64 位程序时缺少包含“bits/c++config.h”

交叉编译:检查是不是可以在 64 位机器上构建 32 位

在 Window 10 的 Visual Studio 中为 64 位编译时,Wow64DisableWow64FsRedirection() 函数不起作用