stdcall由视觉工作室覆盖?

时间:2008-10-17 01:28:04

标签: c++ c windows visual-studio 64-bit

在xp 32bit这行中编译没有问题但是在vista 64bit这行:

m_FuncAddr = ::GetProcAddress (somthing);

给出以下错误

  

错误C2440:'=':无法转换   'FARPROC'到'int(__ cdecl *)(void)'

GetProcAddress定义为

WINBASEAPI FARPROC WINAPI GetProcAddress (somthing)

和m_FuncAddr一样

int (WINAPI *m_FuncAddr)();

据我所知,两者都是stdcall's。

为了避免错误,我必须把

m_FuncAddr = (int (__cdecl *)(void))::GetProcAddress(somthing);

我的问题:

如果m_FuncAddr和GetProcAddress都有stdcall调用约定,为什么我必须用cdecl“调用”它?

VS项目设置'默认调用约定(设置为cdecl)是否可能超越上面的assignemet语句?

提前致谢!

[编辑]

提出问题:

在等式的一边(比如第1面)我有

int __stdcall * m_FuncAddr

另一边(第2面)

INT_PTR far __stdcall GetProcAddress

那么如果两个都是stdcalls的话,我怎么用cdecl来强制转换? 或者我没有得到什么?

2 个答案:

答案 0 :(得分:3)

返回类型应为INT_PTR(64位版本中的64位值)。你不应该抛弃这个错误 - 编译器试图告诉你出了什么问题。

来自WinDef.h:

#ifdef _WIN64
typedef INT_PTR (FAR WINAPI *FARPROC)();

因此m_FuncAddr的声明应为:

INT_PTR (WINAPI *m_FuncAddr)();

答案 1 :(得分:2)

它在32位中正确编译是巧合;正确的语法是:

typedef int (WINAPI *FFuncType)();
FFuncType m_FuncAddr;
m_FuncAddr = (FFuncType)::GetProcAddress (somthing);

您需要将:: GetProcAddress的结果显式地转换为正确的函数签名。在32位,FARPROC恰好使用你拥有的签名,但可能不是64位。

编辑:是的,实际上,看看windef.h,返回类型是64位的INT_PTR,这就是你得到编译错误的原因。您仍然需要按照上面的函数签名转换为任何与FARPROC的占位符不匹配的函数,因此您应该按照上面的方式进行操作。