Allure
Allure

Reputation: 379

Passing another type to a function that takes a void pointer argument

I'm using the GNU Scientific Library which has functions that use void pointers as input. Example:

struct my_f_params { double a; double b; double c; };

double
my_f (double x[], size_t dim, void * p) {
   struct my_f_params * fp = (struct my_f_params *)p;

   if (dim != 2)
      {
        fprintf (stderr, "error: dim != 2");
        abort ();
      }

   return  fp->a * x[0] * x[0] 
             + fp->b * x[0] * x[1] 
               + fp->c * x[1] * x[1];
}

gsl_monte_function F;
struct my_f_params params = { 3.0, 2.0, 1.0 };

F.f = &my_f;
F.dim = 2;
F.params = &params;

I understand this to be defining my_f as a function that takes three arguments, one of which is the void pointer *p. My problem is instead of *p, I want to use a single variable which ranges from -5 to +5. The obvious thing to do is to use a for loop, but the following doesn't run:

float phi;
for (phi = -5.0; phi < 4.5; phi += 0.5) {
        gsl_monte_function G = { &integrator, dim, phi };
        [some code to tell the integrator to integrate]
}

The compiler complains that phi isn't a void pointer. The closest I got to fixing this was to try to convert the type, e.g. with *(float*)phi instead of phi, but it doesn't work - it returns an error saying "invalid cast from type ‘float’ to type ‘float*’". I tried Googling for this but nobody seems to have had this exact problem. What can I do other than repeat the code one time for each value of phi (which works but is very inelegant)?

Upvotes: 0

Views: 1089

Answers (1)

SenselessCoder
SenselessCoder

Reputation: 1159

I understand this to be defining my_f as a function that takes three arguments, one of which is the void pointer *p. My problem is instead of *p , I want to use a single variable which ranges from -5 to +5.

You must realize one thing: What *p is is a struct of 3 doubles, regardless of what you send. Look at your function definition. It is treated as a struct holding 3 doubles. This would be similar to something like this: double m[3]; as it would get casted properly to what you need.

So obviously just sending in phi as a float isn't going to cut it. The way to send it in as a parameter properly with casting is the following: (void *)&phi.

Here's a little example code to help you understand: Sample

Upvotes: 3

Related Questions