在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来强制转换? 或者我没有得到什么?
答案 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的占位符不匹配的函数,因此您应该按照上面的方式进行操作。