VS2019下C++编译遇C2440类型转换错误,C编译正常如何解决?
解决VS2019中C++下BYTE数组转函数指针的C2440错误
首先,问题的核心是C++的类型转换规则比C严格得多:C允许隐式地将数据指针(比如const BYTE*)转换为函数指针,但C++禁止这种不安全的隐式转换,这就是你遇到C2440错误的原因。extern "C"只影响函数的链接方式,和类型转换规则无关,所以它解决不了这个问题。
解决方案:显式使用类型转换操作符
我们需要用const_cast移除CODE的const限定,再用reinterpret_cast完成数据指针到函数指针的显式转换(这是C++中唯一允许这种跨类型转换的合法方式)。
修改后的完整代码如下:
inline BOOL FupVmCall(ULONG_PTR hypercall_number, void* context) { #pragma section(".asm", read, execute) __declspec(allocate(".asm")) static const BYTE CODE[] = { 0x0F, 0x01, 0xC1, // vmcall 0x74, 0x0E, // jz short errorWithCode 0x72, 0x04, // jb short errorWithoutCode 0x48, 0x33, 0xC0, // xor rax, rax 0xC3, // retn // errorWithoutCode: 0x48, 0xC7, 0xC0, 0x02, 0x00, 0x00, 0x00, // mov rax, 2 0xC3, // retn // errorWithCode: 0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, // mov rax, 1 0xC3 // retn }; typedef unsigned char(__stdcall * AsmVmxCallType)( _In_ ULONG_PTR hypercall_number, _In_opt_ void* context ); // 关键修改:先移除const限定,再显式转换为函数指针 #pragma warning(suppress : 4055) AsmVmxCallType AsmVmxCall = reinterpret_cast<AsmVmxCallType>(const_cast<BYTE*>(CODE)); __try { return AsmVmxCall(hypercall_number, context) == 0; } __except (EXCEPTION_EXECUTE_HANDLER) { SetLastError(GetExceptionCode()); return FALSE; } }
补充说明
为什么需要
const_cast?
因为CODE是const BYTE数组,它的地址类型是const BYTE*,而函数指针指向的是可执行代码,没有const限定。这里移除const是安全的——我们已经把CODE放在了标记为可执行的.asm段,确实要执行这段机器码。为什么用
reinterpret_cast?
C++标准明确规定,只有reinterpret_cast允许在数据指针和函数指针之间进行转换,这是替代C语言隐式转换的标准写法。关于
#pragma warning(suppress : 4055)
即使使用了显式转换,VS仍然可能触发4055警告(数据指针到函数指针的转换提示),保留这个编译指令可以抑制该警告,避免不必要的编译干扰。
内容的提问来源于stack exchange,提问作者Roger Feng
相关产品推荐
相关产品推荐

