void**
означает указатель на void*
объект.Но в этом коде нет объекта void*
, на который можно было бы указать!void**
НЕ означает «указатель на любой вид указателя», поэтому, пожалуйста, избегайте его использования как такового.Если у вас есть указатель на что-то, что может быть int*
, может быть double*
или т. Д., void*
лучше, чем void**
.Еще лучше будет шаблон или std::variant
или std::any
.
Но если вам нужно использовать библиотеку, которая использует void**
для обозначения "указателя на указатель на тип, неизвестный во время компиляции"или что-то в этом роде, вам может понадобиться создать указатель void*
для работы, или вам может понадобиться добавить в приведения, чтобы обойти тот факт, что компилятору не нравится это преобразование (по уважительной причине).Проблема в том, что есть как минимум два разумных способа сделать это!(В конечном итоге они будут делать одно и то же на многих распространенных компьютерных архитектурах, но это не гарантируется.)
// LibraryFunc1 takes a void** argument that somehow means an int* pointer.
// But which call is correct?
int* data_in = generate_data();
LibraryFunc1(reinterpret_cast<void**>(&data_in)); // ?
void* p1 = data_in;
LibraryFunc1(&p1); // ?
// LibraryFunc2 returns a void** argument that somehow means an int* pointer.
void** p2 = LibraryFunc2();
int* data_out_1 = static_cast<int*>(*p2); // ?
int* data_out_2 = *reinterpret_cast<int**>(p2); // ?
Основываясь на показанном определении функции, безопасное использование, к сожалению:
void* tmpEvt;
X742_DecodeEvent(evtptr, &tmpEvt);
auto* Evt = static_cast<CAEN_DGTZ_X742_EVENT_t*>(tmpEvt);
, поскольку библиотечная функция предполагает в *Evt = Event;
, что *Evt
на самом деле является void*
объектом, который она может изменить.Обычно вместо этого может работать более простая вещь:
CAEN_DGTZ_X742_EVENT_t* Evt = NULL;
X742_DecodeEvent(evtptr, reinterpret_cast<void**>(&Evt));
, но это стандарт C ++, и это может привести к неправильным действиям на некоторых архитектурах.
Вы можете сделатьисправить это проще, обернув его в функцию:
inline CAEN_DGTZ_X742_EVENT_t* Get_X742_DecodeEvent(char* evtPtr)
{
void* tmpEvt;
X742_DecodeEvent(evtPtr, &tmpEvt);
return static_cast<CAEN_DGTZ_X742_EVENT_t*>(tmpEvt);
}