2

I'm using openCV and need some callback function. these callback function just accept limited parameters. So, if I need more variables for those function, I must make a global variables and turn it around between functions.

For example, here is the callback function :

    void mouse_callback(int event, int x, int y, int flags, void* param);
// params : addition parameter, and just one, I need more parameters for this callback.
// but cannot, so make global variable.

And because I shouldn't do that (make global variable), so I decided to make array of (void*) but I afraid C cannot make this, because size of each members can be different.

My question is : can we make array of (void*), and if not, how can I overcome my problem : use callback function and don't need to make global variable.

Thanks :)

8
  • 3
    Create a struct with all of your data in it and then cast it to void*? Commented Aug 14, 2012 at 16:12
  • stackoverflow.com/questions/7262012/array-of-void-pointers-in-c Commented Aug 14, 2012 at 16:12
  • @LuchianGrigore ah, yes, we know the size of (void*). I'm sorry. but, I still cannot use as : (void*) a[]; Commented Aug 14, 2012 at 16:12
  • a pointer is alway 32bit size in a 32bit computer, so int *, char *, void * is same size. Just try: void *a[SIZE] Commented Aug 14, 2012 at 16:13
  • @BìnhNguyên, that's not necessarily true. Only thing guaranteed is that any pointer type can be converted to void* and back again. Commented Aug 14, 2012 at 16:17

3 Answers 3

7

Define a struct that is capable of holding all necessary values and pass its address as the param argument:

struct my_type
{
    int i;
    char c;
};

void my_mouse_callback(int event, int x, int y, int flags, void* param)
{
    struct my_type* t = param;
}

Not sure what the registration mechanism is but you need to ensure that the lifetime of the object pointed to by param is valid for the calling period of the callback function:

struct my_type* mouse_param = malloc(sizeof(*mouse_param));
mouse_param->i = 4;
mouse_param->c = 'a';

register_mouse_callback(my_mouse_callback, mouse_param);

Specifically, don't do this:

{
    struct my_type mouse_param = { 4, 'a' };
    register_mouse_callback(my_mouse_callback, &mouse_param);
} /* 'mouse_param' would be a dangling pointer in the callback. */
Sign up to request clarification or add additional context in comments.

Comments

3

You can make array of void * because a pointer has a definite size, however, you cannot use these pointers without casting them.

Comments

1

You need to send a void* that points to a struct with your parameters. In the callback function you cast this type (void*) back to the struct* with your params like this:

typedef struct {
  int event;
  int x;
  int y;
  int flags;
} params;

void mouse_callback(void *data) {
   params* param  = (params*) data;
   // now you can use param->x or param->y to access the parameters
}

To pass parameters you need create a paramstruct and cast its address to (void*):

paramstruct myparams;
myparams.x = 2;
myparams.y = 1;

mouse_callback( (void*) &myparams );

5 Comments

Right... (void*) &params, when calling the function is not needed. But it clarifies what it happening, thought.But the cast "(paramsstruct*) data" is needed... or is at least better written code ;-)
Neither cast is necessary, nor clarifies anything at all. The implicit conversion rules are and should be clear to any C programmer and it's obvious what the type of local variable param will be anyway.
I'm very sure you'll get some nerving warnings when compiling using "gcc -Wall"; Good coding style also means to write code in a way, that a compiler accepts it without warnings.
I'm rather sure you won't, as long as it's C you're compiling.
You are right! Tested without explicit casts, saved&compiled from .c-File. No warnings were producted, even using -Wall. Ergo: You'll never know everything ;-) Thanks for that lesson...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.