How do I cast int** to void**? - c++

With the following snippet:
int n = 11;
int* c = &n;
void** v = &c;
I receive the following error in visual studio:
the value of type int** cannot be used to initialize an entity of type void **.
This works fine:
int n = 11;
int* c = &n;
void* v = c;
But this code snippet is for a larger problem in someone's library.
What am I doing wrong with casting a variable to void**?
Complete Example
Using the caen digitizer library the way they try to collect data from the peripheral device has this prototype:
/******************************************************************************
* X742_DecodeEvent(char *evtPtr, void **Evt)
* Decodes a specified event stored in the acquisition buffer writing data in Evt memory
* Once used the Evt memory MUST be deallocated by the caller!
*
* [IN] EventPtr : pointer to the requested event in the acquisition buffer (MUST BE NULL)
* [OUT] Evt : event structure with the requested event data
* : return 0 = Success;
******************************************************************************/
int32_t X742_DecodeEvent(char *evtPtr, void **Evt);
And this is the implementation:
int32_t X742_DecodeEvent(char *evtPtr, void **Evt) {
CAEN_DGTZ_X742_EVENT_t *Event;
uint32_t *buffer;
char chanMask;
uint32_t j,g,size;
uint32_t *pbuffer;
uint32_t eventSize;
int evtSize,h;
evtSize = *(long *)evtPtr & 0x0FFFFFFF;
chanMask = *(long *)(evtPtr+4) & 0x0000000F;
evtPtr += EVENT_HEADER_SIZE;
buffer = (uint32_t *) evtPtr;
pbuffer = (uint32_t *) evtPtr;
eventSize = (evtSize * 4) - EVENT_HEADER_SIZE;
if (eventSize == 0) return -1;
Event = (CAEN_DGTZ_X742_EVENT_t *) malloc(sizeof(CAEN_DGTZ_X742_EVENT_t));
if (Event == NULL) return -1;
memset( Event, 0, sizeof(CAEN_DGTZ_X742_EVENT_t));
for (g=0; g<X742_MAX_GROUPS; g++) {
if ((chanMask >> g) & 0x1) {
for (j=0; j<MAX_X742_CHANNEL_SIZE; j++) {
Event->DataGroup[g].DataChannel[j]= malloc(X742_FIXED_SIZE * sizeof (float));
if (Event->DataGroup[g].DataChannel[j] == NULL) {
for (h=j-1;h>-1;h++) free(Event->DataGroup[g].DataChannel[h]);
return -1;
}
}
size=V1742UnpackEventGroup(g,pbuffer,&(Event->DataGroup[g]));
pbuffer+=size;
Event->GrPresent[g] = 1;
}
else {
Event->GrPresent[g] = 0;
for (j=0; j<MAX_X742_CHANNEL_SIZE; j++) {
Event->DataGroup[g].DataChannel[j] = NULL;
}
}
}
*Evt = Event;
return 0;
}
I use this by:
CAEN_DGTZ_X742_EVENT_t* Evt = NULL; // Creating my event pointer
//Doing some config of the device
X742_DecodeEvent(evtptr, &Evt); //Decode the event data for me to read (Throws error)
Hope this gives some context.

void** means a pointer to a void* object. But there is no void* object in that code to point at! void** does NOT mean "a pointer to any kind of pointer", so please avoid using it as such. If you have a pointer to something which might be an int*, might be a double*, or etc., void* is a better type than void**. Even better would be a template or std::variant or std::any.
But if you have to use a library that is using void** to mean "a pointer to a pointer to a type unknown at compile time" or something like that, you might need to create a void* pointer to work with, or might need to add in casts to get around the fact that the compiler doesn't like this conversion (for good reason). The problem is, there are at least two reasonable ways to do this! (They will end up doing exactly the same thing on many common computer architectures, but this is not guaranteed.)
// 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); // ?
Based on the function definition shown, the safe usage is unfortunately:
void* tmpEvt;
X742_DecodeEvent(evtptr, &tmpEvt);
auto* Evt = static_cast<CAEN_DGTZ_X742_EVENT_t*>(tmpEvt);
since the library function assumes at *Evt = Event; that *Evt is actually a void* object it can modify. It may usually work to do the simpler thing instead:
CAEN_DGTZ_X742_EVENT_t* Evt = NULL;
X742_DecodeEvent(evtptr, reinterpret_cast<void**>(&Evt));
but this is undefined behavior by the C++ Standard, and might do the wrong thing on some architectures.
You could make the correct way easier by wrapping it in a function:
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);
}

What am I doing wrong with casting a variable to void**?
There is no meaningful way to convert int** to void**, so what you're trying to do is wrong.
What you may do is
int n = 11;
void* c = &n;
void** v = &c;
But without a complete example, it is not possible to say whether applies to your problem.

That's simply how the language works.
void * pointers get special treatment: a pointer to an arbitrary type can be converted to a pointer to void (as long as doing so doesn't remove cv-qualifiers from the pointer).
void ** gets none of that special treatment. It's just a regular pointer type, like int **.
int32_t X742_DecodeEvent(char *evtPtr, void **Evt)
Since you want to pass CAEN_DGTZ_X742_EVENT_t ** to your function, you should change the parameter type accordingly: CAEN_DGTZ_X742_EVENT_t **Evt.
In comments you were suggested to use void ** v = (void**)&c;.
While you could probably make it work in practice, strictly speaking any access to *v would violate strict aliasing and cause undefined behavior. I wouldn't use that solution.

Related

Pass function pointer to xTaskCreate with void* pvParameters

Is it possible to pass a function pointer as the parameter for the freeRTOS xTaskCreate function?
I suspect I need to cast the void* pvParameters within the task before I can call it but I am not sure what such as cast would be.
class param
{
private:
//Initialized during construction to hardware specific value.
uint8_t mParam = 0;
public:
uint_8 getParam() {return mParam;}
};
void task(void* pvParameters)
{
//get hardware specific pvParameters.
uint8_t hwParam = pvParameters();
// Do task things.
}
main()
{
param p;
uint32_t result;
result = xTaskCreate(task, "Task", configMINIMAL_STACK_SIZE, (void *)&p.getParam, configMAX_PRIORITIES - 1, nullptr); //lint !e712 implicit conversion from long to int
if (result == 0)
{
//print error msg.
}
else
{
vTaskStartScheduler();
for(;;) {ASM("NOP");}
}
}
Why not using &p (address of object p) as argument to access the complete param object using a cast like this:
param& p = *(param*)pvParameters;
Beware that for a number of ports/MCUs the main stack is reused as ISR stack and main stack allocated arguments might get corrupted. Better use e.g. static/new param object.

Dereferencing void pointer to assign value to struct

I have several structs containing various combinations of parameters. I wrote a function that takes a void pointer reference to the structs (there are several different types), and writes information from the data parameter into them. Here's the function below:
void SubModelBase::writeDataStruct(byte msgID, void *ptr, QByteArray data)
{
*(byte*)ptr[0] = msgID;
*(byte*)ptr[1] = data.length();
for (int i = 2; i < data.length(); i++)
{
*(byte*)ptr[i] = data.at(i);
}
}
The void *ptr is the reference to the struct that I want to write the data into but I'm having issues deferencing the pointer so I can write into it. I'm sure I'm just missing something silly in my syntax here but I'm not seeing it at the moment...
EDIT:
Ok, I rewrote the function to first cast the void pointer to a byte pointer before assigning values:
void SubModelBase::writeDataStruct(byte msgID, void *ptr, QByteArray data)
{
byte* structData = (byte*)ptr;
structData[0] = msgID;
structData[1] = data.length();
for (int i = 0; i < data.length(); i++)
{
structData[i + 2] = data.at(i);
}
}
Not tested yet but now it at least compiles. I did it this way because there are over 30-40 different structs that need to have data filled in them and I needed a single function that can handle the operation easily without knowing the details of each struct. However, if there is a better way to approach the problem, I'm definitely open to ideas.
EDIT 2: Fixed logic error in loop
What you seem to be looking for is a template so the compiler creates the correct method when you need it.

Casting a pointer when passing it as an argument for void* parameter

Lets have following function:
int encode(uint8b *dest, MyType srcType, const void *src)
{
uint32b value = 0;
uint64b value64 = 0;
switch (srcType)
{
case MyType_Usint: value = (uint32b)*(uint8b*)src; break;
case MyType_Uint: value = (uint32b)*(uint16b*)src; break;
case MyType_Udint: value = *(uint32b*)src; break;
case MyType_Ulint: value64 = *(uint64b*)src; break;
}
// now encode value to dest
}
I have passed wrongly aligned uint8b Data[sizeof(uint64b)]as src, I will fix the alignment.
But I received a demand to cast Data when calling the function to proper type, i.e. encode(dest, MyType_Uint, (uint16b*)Data), which I think would cause in some more annoying unnecessary switches.
It's working even with the wrong alignment on platforms accessible for me, but I'm not sure, how it affects the other.
Would such cast fix alignment and/or endianess?
And yes, I really need the void* parameter.
encode(dest, MyType_Uint, (uint16b*)Data)
Would such cast fix alignment and/or endianess?
Such cast does not fix alignment nor endiannes.
The way to call that function without undefined behaviour is following:
uint16b u = some_value;
encode(dest, MyType_Uint, &u);
uint64b ul = some_other_value;
encode(dest, MyType_Ulint, &ul);
Does such cast actually do anything?
Such cast changes the type of the expression. In this case, the C style explicit conversion does reinterpret cast.
The converted pointer can be used only in limited ways. You can convert it back to the original type (uint8b* in your case). Indirection through the pointer is UB in most cases, with few exceptions, which include pointer-interconvertible objects, as well as using a pointer to a narrow character type as the result of the conversion. There is no exception that would apply to your example, so it would have UB.
Note that for some pointers, the C style explicit conversion does static cast, rather than reinterpret cast. For example, when the pointers are to classes in the same inheritance hierarchy. This is why C style casts are to be avoided: Use the cast that you intend to use.
Casting a pointer never fix alignment nor endianness. It just re-interpret the address as pointing to a different type, and standard does not allow to de-reference it unless an object of the appropriate type lies at that address.
The conformant way to use a possibly misaligned representation is to use memcpy:
int encode(uint8b *dest, MyType srcType, const void *src)
{
uint32b value = 0;
uint64b value64 = 0;
switch (srcType)
{
// any object can be accessed through a char pointer
case MyType_Usint: uint8b tmp8 = *(uint8b*)src; value = tmp8; break;
// use a temporary for 16 bits type (endianness question)
case MyType_Uint: uint16b tmp16; memcpy(&tmp16, src, sizeof(tmp16));
value = tmp16; break;
// directly memcpy into the value when size is the same
case MyType_Udint: memcpy(&value, src, sizeof(value)); break;
case MyType_Ulint: memcpy(&value64, src, sizeof(value64)); break;
}
// now encode value to dest
}
Intel type (80x86 to core) are known to be tolerant to misalignment, but other processors are not and raise an error if you attempt a misaligned access.
This code is unlikely to work on platform that can't do unaligned memory access (like ARM9/ARM64 etc...).
This is because when you do value64 = *(uint64b*)src you expect the CPU to access a 8 bytes word (and as such it must be aligned to 64bit address) and the signature of the function does not guaranty this.
Typically, on such platform, calling:
char s;
int a = encode(dest, MyType_Ulint, &s);
will compile, and will crash at runtime (but will run ok on x86/amd64 system, yet with undefined behavior).
If you want something portable, you should do something like this:
enum MyType
{
MyType_Usint,
MyType_Uint,
MyType_Udint,
MyType_Ulint
};
int encode(uint8b *dest, MyType srcType, const void *src)
{
uint32b value = 0;
uint64b value64 = 0; // This is guaranted to be aligned for 64bit access
size_t expected_operand_size[] = { 1, 2, 4, 8 };
memcpy(&value64, src, expected_operand_size[(int)srcType]);
switch (srcType)
{
case MyType_Usint: value = *(uint8b*)&value64; break;
case MyType_Uint: value = *(uint16b*)&value64; break;
case MyType_Udint: value = *(uint32b*)&value64; break;
case MyType_Ulint: break;
}
// now encode value to dest
}
By the way, you should use template code here for convenience and to avoid the (useless) copy and be easier to understand (no need to have an type enum) :
template <typename T>
struct Encode
{
static uint64b convert(const void * src) { T t; memcpy(&t, src, sizeof(t)); return t; }
static uint64b convert(const T * src) { return *src; }
};
// Specialisation when we can avoid the copy
template <>
struct Encode<uint8b>
{
static uint64b convert(const void * src) { return (uint8b)*src; }
static uint64b convert(const uint8b * src) { return *src; }
};
template <typename T>
int encode(uint8b * dest, const void* src)
{
uint64b value64 = Encode<T>::convert(src);
// your encoding code here
}
// Use like this:
void * s = ...;
uint16b * s2 = ...;
uint32b * s3 = ...;
encode<uint8b>(dest, s); // No copy, calls Encode<uint32b>::do(const void*)
encode<uint16b>(dest, s2); // No copy, calls Encode<uint16b>::do(const uint16b*)
encode<uint32b>(dest, s3); // No copy, calls Encode<uint32b>::do(const uint32b*)
// or this is also safe
encode<uint16b>(dest, s); // Copy here for fixing alignment

How do I cast a pointer to a C++ struct with data members to a pointer to a C++ struct which has no data members?

How do I cast a pointer to a C++ struct with data members to a pointer to a C++ struct which has no data members such as:
struct libusb_device_handle?
For example , On windows 7 , I would like to cast a C++ pointer to HRAWINPUT to a C++ pointer to a C++ struct which has no data member such as libusb_device_handle
for (size_t idx = 0; idx < count; ++idx) {
libusb_device *device = list[idx];
libusb_device_descriptor desc = { 0 };
rc = libusb_get_device_descriptor(device, &desc);
if (desc.idVendor == MY_VID &&
desc.idProduct ==MY_PID) {
libusb_device_handle *handle;
libusb_open(device, &handle); libusb_claim_interface(handle, 0);
return (HRAWINPUT *)&handle;
}
}
The reason I want to do this is shown here:
I have already opened the CH Products VM Desktop joystick device via libusb_open(). Then, I would like to do some magic (meaning polling for events) such as invoking GetRawInputData() on the casted version of pointer to libusb_device_handle so as to record the x and y coordinates when we move the joystick vigorously.
Any help is greatly appreciated.
You cannot just cast pointers to structures and assume things will work. By casting a pointer you are simply telling the compiler for example that a pointer to say a double should be considered instead a pointer to an std::string instance. This is normally a very bad idea and will not convert the double into a std::string.
In the specific you should follow the Microsoft API specifications for raw input reading from a Joystick; a tutorial can be found for example here.

Function Pointer basic question

I have a basic question on function pointer.
In the below code snippet, how do I read this "
*(FARPROC*)&pfn ="?
IFastString *CallCreateFastString(const char *psz) {
static IFastString * (*pfn)(const char *) = 0;
if (!pfn) {
const TCHAR szDll[] = _TEXT("FastString.DLL");
const char szFn[] = "CreateFastString";
HINSTANCE h = LoadLibrary(szDll);
if (h)
*(FARPROC*)&pfn = GetProcAddress(h, szFn);
}
return pfn ? pfn(psz) : 0;
}
This isn't really about function pointers, but about casting in general.
Suppose pfn is of type T. Then &pfn is of type T*. This gets cast to FARPROC* by the cast expression (the stuff in the parentheses). Finally, this gets dereferenced, yielding a FARPROC&.
All in all this just means you're treating pfn as if it were of type FARPROC and assign a value to it.
Here's a generic example:
S make_an_S();
T x;
T * const px = &x;
S * const py = (S*)px;
*py = make_an_S(); // same as *(S*)&x = make_an_S();
*(FARPROC*)&pfn = GetProcAddress(h, szFn);
is equivalent to,
(FARPROC)pfn = GetProcAddress(h, szFn);
So, pfn is a function pointer which is type casted to FARPROC to store the address received from GetProcAddress(h, szFn).
[Note: I am not sure, if this kind of typecasting is deprecated in C++.]