错误 C2440,“static_cast”: 无法从UNIT转为UINT_PTR的解决(【转】)
从Win32到Win64的OnTimer函数问题:
OnTimer函数相关的错误是将应用程序从Win32系统移植到Win64系统时遇到的最常见的错误。函数OnTimer几乎在每个应用程序中使用,您可能会遇到一些编译错误。早期(在Visual Studio 6中)此函数具有原型“OnTimer(UINT nIDEvent)”,并且最有可能以相同的形式出现在用户类中。现在这个函数有原型“OnTimer(UINT_PTR nIDEvent)”,它会导致64位系统的编译错误。
例子:
class CPortScanDlg : public CDialog
{
...
afx_msg void OnTimer(UINT nIDEvent);
...
};
BEGIN_MESSAGE_MAP(CPortScanDlg, CDialog)
...
ON_WM_TIMER()
END_MESSAGE_MAP()
对于此代码,在编译阶段将公布以下错误:
1>.\Src\Portscandlg.cpp(136) : error C2440: 'static_cast' :
cannot convert from 'void (__cdecl CPortScanDlg::* )(UINT)' to
'void (__cdecl CWnd::* )(UINT_PTR)'
1> Cast from base to derived requires dynamic_cast or static_cast
错误关键是函数类型在宏ON_WM_TIMER中显式转换:UINT和UINT_PTR:
#define ON_WM_TIMER() \
{ WM_TIMER, 0, 0, 0, AfxSig_vw, \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT_PTR) > \
( &ThisClass :: OnTimer)) },
解释:构建32位版本时转换能成功,是因为UINT和UINT_PTR类型重合。但是在64位模式下,这些是不同的类型,并且函数类型转换是不可能的,并且导致编译错误。
错误修复
此错误很容易修复。您应该在用户类中更改函数OnTimer的定义。以下是更正后代码的示例:
class CPortScanDlg : public CDialog
{
...
afx_msg void OnTimer(UINT_PTR nIDEvent); //Fixed
...
};
有时OnTimer函数不止一次在程序中使用。
我们建议您在编译之前搜索“OnTimer(UINT”行),并将其替换为“OnTimer(UINT_PTR”。您也可以使用“查找和替换”功能。如下图:
注意:不要忘记,线的末端必须有一个空格。如果没有空格,您将获得“OnTimer(UINT_UINT_PTR nIDEvent)