我试图从开发c ++代码转移到Visual Studio 2017,然后我的代码无法工作,因为它说expression must be a pointer to a complete object type
所以我试图弄清楚发生了什么,但我坚持如何解决它。
void print_function_instructions(void *func_ptr, size_t func_len) {
for (unsigned char i = 0; i < func_len; i++) {
unsigned char *instruction = (unsigned char*)func_ptr + i;
printf("%p (%2u): %x\n", func_ptr + i, i, *instruction); # expression must be a pointer to a complete object type
}
}
int change_page_permissions_of_address(void *addr) {
// Move the pointer to the page boundary
int page_size = getpagesize();
DWORD dwOldProtect;
addr -= (unsigned uintptr_t)addr % page_size; #expression must be a pointer to a complete object type
if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
return -1;
}
return 0;
}
你从gcc(最常用于Dev C ++的编译器)中学到了一个坏习惯。虽然它在许多方面与C ++标准很好地兼容,但它在一个方面却很糟糕。根据标准,你不允许对void指针进行任何算术运算。
void指针基本上只是设计为“持有者”。您可以将指向任何对象类型的指针放入void指针中,稍后您可以将其取回 - 但实际上您无法在void指针本身上执行任何类似指针的操作(取消引用或指针算术)。
gcc在这方面失败了。虽然它不会让你取消引用void指针,但它会让你对void指针进行算术运算。当你这样做时,它会把它看作是一个指向char的指针,所以如果你增加或减少它,它就会以一个为单位发生。
为了支持算术,你可能想要创建一个指向(可能是unsigned)char的指针,并对其进行算术运算:
void print_function_instructions(void* fptr, size_t func_len) {
unsigned char* func_ptr = reinterpret_cast<unsigned char*>(fptr);
for (unsigned char i = 0; i < func_len; i++)
printf("%p (%2u): %x\n", func_ptr + i, i, func_ptr[i]);
}
int change_page_permissions_of_address(void* address) {
// Move the pointer to the page boundary
unsigned char* addr = reinterpret_cast<unsigned char *>(address);
int page_size = getpagesize();
DWORD dwOldProtect;
addr -= (uintptr_t)addr % page_size;
if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
return -1;
}
return 0;
}
你不能用void
指针算术
#include <cstdio>
void print_function_instructions(void *func_ptr, size_t func_len) {
for (unsigned char i = 0; i < func_len; i++) {
unsigned char *instruction = (unsigned char*)func_ptr + i;
printf("%p (%2u): %x\n", instruction, i, *instruction);
}
}
而不是打印func_ptr + i
,你应该打印instruction
,用func_ptr + i
初始化,但将func_ptr
施放到char*
。 Void没有定义的大小(不能用它做指针算术),char
的大小为1。