将c ++从dev c ++移植到visual c ++

问题描述 投票:-1回答:2

我试图从开发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;
}
c++ visual-c++
2个回答
3
投票

你从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;
}

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。

© www.soinside.com 2019 - 2024. All rights reserved.