2017-01-05 4 views
0

Вот некоторые примеры классов, чтобы воспроизвести ситуацию, я столкнулся:C++ Любой указатель в качестве аргумента функции

class A { 
B* seccond; 
} 
class B { 
int * number; 
} 
static NTSTATUS Read(std::uintptr_t address, size_t size, PVOID buff); 

// Let's assume we have object 'obj' which has valid address of number variable 

int buff; 
Read(obj.seccond, sizeof(int), &buff); 

Error: cannot convert argument 1 from 'int *' to 'uintptr_t' 

Я знаю, что это можно легко исправить с:

Read(std::uintptr_t(obj.seccond), sizeof(int), &buff); 

, но это не удовлетворяющий достаточно, так как он снижает читаемость кода, и это просто уродливо. Я действительно не хочу использовать шаблоны, поскольку они уже повсюду по всему моему коду. Существует ли какой-либо простой контейнер для таких переменных? Или еще более элегантный способ сделать это?

EDIT: Я вновь адаптированный вопрос, извините

+2

'std :: uintptr_t' не является типом указателя, это целое число. Неявное преобразование вызовет множество проблем (посмотрите примеры C для истории). – molbdnilo

+1

* Шаблоны уже повсюду по всему вашему коду * ... Сделайте еще один :) –

+0

Я знаю, но дело в том, что я работаю над другим пространством адресов процесса, в структурах которого содержатся указатели, как только я их прочитаю, их следует рассматривать как нормальные uint, которые должны быть переданы в функцию «Чтение». Значит, нет способа сделать это? –

ответ

1

Вы можете использовать перегрузку сделать преобразование в одном месте

static NTSTATUS Read(const void* p, size_t size, PVOID buff) 
{ 
    return Read(std::uintptr_t(p), size, buff); 
} 
+0

Я был так уверен, что попробовал, извините за проблемных парней и спасибо! –

1

Вы используете один int* с момента функции ожидания для uintptr_t. Один подписан, другой - без знака.

Попробуйте использовать unsigned вместо int или попытаться использовать std::intptr_t вместо std::uintptr_t

EDIT: способ решить вашу проблему может быть что-то вроде этого:

class B { 
    int *number; 
    operator int*() { 
     return number; 
    } 
}; 

После, вы можете сделать что-то вроде: Read(*objA.second, ...);

Ответ от Jarod42 может быть хорошим!

+0

Я, вероятно, неправильно задал свой вопрос, не могли бы вы сейчас взглянуть? Проблема не подписана - unsigned, но обязательное преобразование в std :: uintptr_t, которое содержит адрес объекта в памяти. –

+0

Посмотрите на мое редактирование и посмотрите на ответ от @ Jarod42 :). –

0

Я полагаю, вы могли бы использовать указатель недействительным как argument.For например:

static NTSTATUS Read(void* address, size_t size, PVOID buff); 

Но вы, вероятно, следует передать другой аргумент функции, чтобы определить тип, который вы должны использовать для адресной переменной. Например,

static NTSTATUS Read(void* address,unsigned code, size_t size, PVOID buff) 
{ 
    //code could be int=1,float=2,... 
    switch(code) 
    { 
     //handle each case int,float,custom type ... 
     //by casting the address to the corresponding type(code) 
    } 
} 
Смежные вопросы