将32位COM接口迁移至64位编译时遇类型转换错误求助
解决32位COM升级64位时的ATL函数指针类型不匹配错误
错误原因
64位编译下ATL对函数指针的类型和调用约定检查更严格,原32位代码中WINAPI(__stdcall)调用约定的函数指针可被隐式转换,但64位下不允许。COM_INTERFACE_ENTRY_FUNC_BLIND要求的回调函数签名必须匹配ATL::_ATL_CREATORARGFUNC,该类型采用__cdecl调用约定,而你的QueryIMEDDevice使用了WINAPI(__stdcall),导致类型不匹配。
解决方案
修改QueryIMEDDevice的调用约定为__cdecl,去掉WINAPI关键字,使其与_ATL_CREATORARGFUNC的签名完全匹配:
HRESULT __cdecl QueryIMEDDevice(void *pV, REFIID riid, LPVOID *pPV, DWORD dw) { return DTQueryIMEDDevice(reinterpret_cast<CNIDAQmx *>(pV), riid, pPV, dw); } BEGIN_COM_MAP(CNIDAQmx) COM_INTERFACE_ENTRY(INIDAQmx) COM_INTERFACE_ENTRY(IObjectControl) COM_INTERFACE_ENTRY(IObjectConstruct) COM_INTERFACE_ENTRY(ISpecifyPropertyPages) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY_FUNC_BLIND(0, QueryIMEDDevice) COM_INTERFACE_ENTRY2(IDispatch, IMEDADC) COM_INTERFACE_ENTRY(IMEDADC) END_COM_MAP()
验证说明
- 调整调用约定后,函数指针类型将完全匹配
_ATL_CREATORARGFUNC的要求,64位编译时不会再触发C2440错误。 - 若
DTQueryIMEDDevice本身要求特定调用约定,只需保证QueryIMEDDevice的外部签名匹配ATL要求即可,内部调用不受影响。
内容的提问来源于stack exchange,提问作者Gary
相关产品推荐
相关产品推荐

