0
votes

Let's say I have a function which takes these parameters.

int create(Ptr * p,void * (*insert)(void *, void *)) {

//return something later
}

And the struct:

typedef struct {
void ** ptr;
void * (*insert)(void *, void *));
}Ptr;

Where p is a pointer to a struct, and insert is a function pointer to a function with two general pointers (void pointers), to insert a integer in a given tree (I'm using void pointers because in this case it's a integer, in other cases it may not be).

How would I go about calling the function create, here?

I know I can do something along the lines of this for the first parameter:

//in a seperate .c file

Ptr * pt;
pt = malloc(sizeof(Ptr));

create(pt,....what to put here)?

If I wanted to pass the struct pointer as an argument, and an integer to be inserted second (Again they're both void pointers because it is a generic build).

3
I think the design is incorrect. You should define the insert function, and shouldn't pass it as an argument to the create function (as i suppose you don't need to have a separate insert function for every node in the tree). - CristiFati

3 Answers

2
votes

Inside that function, you can write either of:

insert(vp1, vp2);

or:

(*insert)(vp1, vp2);

where I'm assuming:

void *vp1 = …;
void *vp2 = …;

The second is the form that was necessary prior to the C89/C90 standard; you'll find old diehards like me still prefer it. The first is standard since the first version of the standard was published, but you have to look at the function's argument list to find that insert is a pointer to a function instead of the name of function. That's why I still prefer the old notation.

For actually calling the function, you simply give the name of a function that matches the signature of the insert function pointer:

extern void *insert_int(void *vp1, void *vp2);

if (create(pt, insert_int) != 0)
    …handle error…
1
votes

Some compilable example usage:

typedef struct {
  void ** ptr;
  void * (*insert)(void *, void *);
} Ptr;
int create(Ptr * p,void * (*insert)(void *, void *));

void* Insert(void*, void*);

void fun(){
  Ptr ptr;
  Ptr * pt = &ptr;

  //Function name decays to its addresss
  create(pt, &Insert);
  create(pt, Insert);  //the same thing

  //Declare a pointer
  void* (*ins)(void*, void*);
  //Assing to it
  ins = &Insert;
  //Same thing
  ins = Insert;

  //Invocation via pointer
  void* ret = (*ins)(pt, pt);

  //Same thing
  ret = ins(pt, pt);

  //Passs the pointer
  create(pt, ins);
}
0
votes

according to the definition of create...

void*  mine(void* x, void* y)
{
   return NULL
}

create(pt, mine);

and create would be

int create(Ptr * p,void * (*insert)(void *, void *)) {
   p->insert = insert;
}

I'd go with a function to make the call as well

void* ptr_insert(Ptr* p, void* a, void* b)
{
   if(p!=NULL && p->insert != NULL) return p->insert(a,b); 
   return NULL;
}