2

I wrote a function that receives a void * type argument and the plan that I can pass char* and int and in the receiving function I read whatever I expect.

It looks like:

void __declspec(dllexport) void* func(void *);

Next i tried to pass a double here:

double d = 3.14;
(*funcPtr)( (void *)d ); 

but got an error:

error: invalid cast from type 'double' to type 'void*'

Then I gone through method to pass double to void argument thread and tried this way:

double d = 3.14;
double *p_d = (double *)d;
(*funcPtr)( (void *)p_d );

But still the same luck:

error: invalid cast from type 'double' to type 'double*'

What am I missing and how to resolve my problem? I thought a solution would be to define several typedef of function pointers.

NoOb
  • 35
  • 6

3 Answers3

5
double d = 3.14;
double *p_d = &d;

You don't cast from a type to a pointer you need to reference it. When you need to use the value in the pointer you dereference it like so.

double new_d = *p_d;

And inside a function that receives p_d as a void pointer, you'll have to cast the pointer back to a double pointer before use.

Like

void func(void *p_d)
{
    double new_d = *(double*)p_d;
    ...
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
Joe
  • 399
  • 2
  • 7
3

You have two general ways of doing this:

  1. Get a pointer to either the double instance itself, or to a wrapper that holds it. Depending on how you call this thing, this may easily lead to an access violation if the value is held on the stack and your function ends before the called function uses the pointer.
    double val;
    fn(&val);
  1. On a 64-bit system, if you're sure enough in your pointer-fu, you can store it as the pointer itself. Make sure you do the reverse in the called function, it won't be a pointer, it will be the double data itself.
    double v;
    fn((void *)(*(long long *)&v));
Blindy
  • 65,249
  • 10
  • 91
  • 131
1

Similarly to what Blindy suggested it his option 2, I wanted to offer:

double d = 3.14;
void* p;
int id = sizeof d;
int ip = sizeof p;
//p = (void*)d;
memcpy(&p, &d, id);

If NoOb is dealing with a third-party library (judging by __declspec(dllexport)), he may not have a freedom to change interface.

Also, you should not be passing pointers to a library, as you don't know when is it safe to free it (and you can't delegate freeing to the library either).

A void* in C was used as universal storage for ages. If you can make sure that it has enough bits, and you know that the library is not going to derefernce it - just do it.

Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27
  • Do you mean it would be better to pass a pointer to a copy into the library and expect the return to be a what i expect and copy it back into the original that i have sent a copy of? – NoOb Dec 08 '20 at 20:09
  • @NoOb this is not a pointer to a copy; this is YOUR double data, stuffed into a `void*` so that you can call your `func` without conversion or type conflict. Very similar to what Blindy suggested, but more "honest" – Vlad Feinstein Dec 08 '20 at 20:18