如何将uint8_t数组传入函数指针并解析为32位整数输出9034?
问题
需要将uint8_t[]数组作为参数传入定义为typedef void (*dangerousC)(char*);的函数指针,且使用Windows API头文件。假设变量raw是GetProcAddress()返回的函数指针,编译器不知道foo()的参数。现有代码如下:
#include <iostream> #include <Windows.h> typedef void (*dangerousC)(char*); void foo(int a) { std::cout << a << std::endl; } int main() { auto raw = (FARPROC) foo; auto* b = new uint8_t[4]; b[0] = 74; b[1] = 35; b[2] = 0; b[3] = 0; std::cout << *(int*)b << std::endl; auto func = (dangerousC)raw; func(reinterpret_cast<char *>(*b)); delete[] b; }
当前调用func(reinterpret_cast<char *>(*b))时仅得到单个字符,尝试传入指针也无法得到期望的9034,请问如何让函数输出9034,将字节数组完整解析为32位整数?
解决方案
核心问题是函数指针类型不匹配,以及参数传递逻辑错误。要让foo正确接收字节数组对应的32位整数,需对齐参数传递逻辑与foo的实际参数要求:
明确参数传递本质
foo实际需要的是int类型的值传递,而dangerousC定义的函数指针要求传递char*(指针类型)。直接传数组指针会把内存地址作为参数传给foo,这显然不是目标结果。正确的类型转换与调用
最可靠的方式是绕过dangerousC的类型限制,将函数指针重新解释为接收int的类型,再传递字节数组转换后的int值:
auto func = reinterpret_cast<void(*)(int)>(raw); func(*reinterpret_cast<int*>(b));
如果受场景限制必须使用dangerousC类型指针,可利用平台调用约定特性,传递int值的地址(仅在调用约定匹配时有效):
auto func = (dangerousC)raw; func(reinterpret_cast<char*>(&(*reinterpret_cast<int*>(b))));
验证字节序
你的数组b[0]=74, b[1]=35在小端序下对应的int值为35*256 +74 = 9034,当前代码中*(int*)b已能正确输出该值,说明字节序无需调整。修正后的完整代码
#include <iostream> #include <Windows.h> typedef void (*dangerousC)(char*); void foo(int a) { std::cout << a << std::endl; } int main() { auto raw = (FARPROC) foo; auto* b = new uint8_t[4]; b[0] = 74; b[1] = 35; b[2] = 0; b[3] = 0; std::cout << *(int*)b << std::endl; // 转换函数指针为匹配foo参数的类型 auto func = reinterpret_cast<void(*)(int)>(raw); func(*reinterpret_cast<int*>(b)); delete[] b; }
内容的提问来源于stack exchange,提问作者block103
相关产品推荐
相关产品推荐

