5

I have a function which I want to pass through various functions

int func1(char *ptr)
{
    printf("%s",ptr);
    return 0;
}

and other function in which I want to call the func1

int func2(void *i)
{
    //call i
    //here i point to function func1
    //and do something with return value of i
}

So, how should I call it in main()?

int main()
{
    void *d;
    //SOMETHING wrong in next four line
    d=&func1("abcd");
    func2(d);
    d=&func1("xyz");
    func2(d);
    return 0;
}
Gaurav
  • 2,003
  • 1
  • 25
  • 50

5 Answers5

4

You can simply create a function (func2) that takes a function pointer to your desired function that you want called and another paramter that takes a pointer to your string. Then in func2 call the passed in function pointer with the str argument.

#include <stdio.h>

void func1(const char *str)
{
    puts(str);
}

void func2(void (*fp)(const char *), const char *str)
{
    fp(str);
}

int main(void)
{
    const char *str = "Hello world.";

    func2(func1, str);

    return 0;
}
Kludas
  • 571
  • 4
  • 7
  • @kludas yes thats the most appropriate way. but i saw one of gauravmeena's comments that the func2 is a lib function and that only void pointer was allowed. you could also pass a struct with the function pointer and the string(as char *)as members and recast it back to struct in func2? – Koushik Shetty Feb 20 '13 at 12:26
  • @Koushik yes it was the constraint for me, but in your answer you put string in func2 .... Kludas can also do that and make func2 with one parameter as input. The only way to pass string from main is to use struct as you suggested – Gaurav Feb 21 '13 at 05:20
  • @gaurav in my answer the func2 parameter is void *, func1 has char *. and yes struct is more appropriate because you cannot change your func2 definition. and if it was designed right then i guess it will be expecting a struct itself. – Koushik Shetty Feb 21 '13 at 05:37
2

You should first of all use Function pointers to do the job you desire. Using void pointer is a method where you before hand know what you will cast it to for dereferencing. Since you are passing the address of a function, you should cast it to a function pointer anyways. So avoid all this and declare func pointer anyways. Use void * only if you know that you can handle all the possiblities. eg. memcpy uses void * this is acceptable as you just want a bunch of data in soure location to be copied to a destination location.

#include <stdio.h>
void func1(char * str)
{
   printf("%s",str);
}
void func2(void * g)
{
   void (*p) (char *);   //function pointer
   p = (void (*)(char *))g;//casting void * to pi.e func pointer reqiuired eitherways.
   p("Func pointer caller");
}
void main()
{
   void * d = func1; // name of the function is itselt its address
   //printf("func1 = %d\nd = %d",func1,d);  
   func2(d);
}

all this can be avoided by a simple function pointer.

bwoebi
  • 23,637
  • 5
  • 58
  • 79
Koushik Shetty
  • 2,146
  • 4
  • 20
  • 31
  • Though it did leave one issue (sending *str from main) ... It is the functionality I wanted. Thanks – Gaurav Feb 20 '13 at 08:21
  • @gauravmeena0708 yes it does not give this functionality as there is no direct way of doing this. There might be workarounds for this but they will only be workarounds for this particular situation but not a general workaround. – Koushik Shetty Feb 20 '13 at 08:49
  • The C Standard doesn't allow casting a function pointer to a data pointer and vice versa. http://stackoverflow.com/a/5579907/1005312 – Kludas Feb 20 '13 at 09:21
  • @Kludas so what's the alternative way to achieve this – Gaurav Feb 20 '13 at 09:44
  • 1
    @gauravmeena0708 Look at my answer provided below. – Kludas Feb 20 '13 at 11:12
2

First of all: A function pointer refers to a function only. Parameters come into the game when the function is called, either directly or via a function pointer.

So if you want to achieve what you have in mind, that is binding a (set of) parameters to a specific function varaible you need to use a wrapper function:

int func1(char * pc)
{
  int i;
  /* assigne somehting to "i" and use "pc" */
  return i;
}

int func1_abcd(void)
{
  return func1("abcd")
}

int func1_xyz(void)
{
  return func1("xyz")
}

typedef int (*pfunc1_wrapper_t)(void);

int func2(pfunc1_wrapper_t pfunc1_wrapper)
{
  return pfunc1_wrapper();
}

int main(int argc, char ** argv)
{
  pfunc1_wrapper_t pfunc1_wrapper = NULL;
  int i = 0;

  pfunc1_wrapper = func1_abcd;
  i = func2(pfunc1_wrapper);

  pfunc1_wrapper = func1_xyz;
  i = func2(pfunc1_wrapper);

  ...

  return 0;
}
alk
  • 69,737
  • 10
  • 105
  • 255
1

Refer this Function pointers and read up on Wiki - Function Pointers, and you'll know how to fix your code.

Community
  • 1
  • 1
Jatin Ganhotra
  • 6,825
  • 6
  • 48
  • 71
  • 1
    A good answer in SO's spirit contains at least a minimal answer to the question. References then could help clarifing the details or contain examples. – alk Feb 20 '13 at 08:29
0

Jatin already posted a general link to function pointers, very good explaining function pointers.

As you seam to want to pass not a classic function pointer, but a function pointer WITH it's argument as one "function pointer" to an other function, I do not think that this will work.

But why passing a function with its argument as one parameter? This would mean, that the function you are passing with parameters, will return only one result, that is already known outside func2 (as func2 will call func1 with this already outside defined parameter set). So why not just pass the result of the func1 call to func2?

JokoFacile
  • 143
  • 5
  • func2 is a library function and can take only void * values. so I can either pass address of a function or a structure... I just wanted to try this way. – Gaurav Feb 20 '13 at 07:50
  • In this case (as you can not pass function parameters for func1 to func2) I would either call func1 with its parameteres outside func2 and just pass the result. If you cannot get the result in a passable format, you could do a func3, calling func1 with its parameters and pass a function pointer to func3 to func2. This way you have a function pointer to a function without parameters. – JokoFacile Feb 20 '13 at 08:05
  • yes realized that so either i pass two vars or struct...like @Kludas did in his solution – Gaurav Feb 20 '13 at 12:12