Scenario:
There are multiple C structs, each of which contains a function pointer to the same function. These pointers can be different if necessary (pointers to pointers, etc.), but must all point, eventually, to the same function.
Problem:
When the function is called from one of the pointers, I need to retrieve, within the function, which struct it was called from.
e.g.
typedef struct A {
void * (*func)();
... /* Custom properties */
} * A;
typedef struct B {
void * (*func)();
... /* Custom properties */
} * B;
A a_init() {
A a;
... /* Custom initialisation, allocation, etc. */
a->func = myFunc;
return a;
}
B b_init() {
B b;
... /* Custom initialisation, allocation, etc. */
b->func = myFunc;
return b;
}
int main () {
A a = a_init();
void *something = a->func();
}
void * myFunc () {
// Need to get pointer to the instance of the struct this was called from here
}
Is there any way I can retrieve a pointer to the caller within myFunc? If necessary, I was thinking of creating pointers to pointers, etc. to the function, so each instance of an object would have a different pointer, and store all of them in a central location to match them up, but that obviously won't work if I can't even find the instance of the object or the pointer which was used. Any ideas?
Edit:
The question was intended a bit more broadly than I seem to have put it. Currying would be a great solution, if anyone has any ideas as to how to implement it in C. I had some ideas, but I just ended up coming right back to this spot with it.
I don't think there is any way within the language to do that, without explicitly passing some identifier (as an argument or a global) to myFunc. The address of a_init() exists somwhere within the call stack, but it's not accessible from the program.
It's like if somebody showed up at your door unannounced, how would you find out where that person came from without asking?
You can't do that. What you may do, however, is define your structs like this:
typedef struct A {
/* ... */
void *(*func)(void *);
} A;
typedef struct B {
/* ... */
void *(*func)(void *);
} B;
And your function like this:
void *myFunc(void *the_struct) {
/* ... */
}
And call like this:
A a = a_init();
void *something = a->func(a);
Alternatively, if you don't care about portability and for some reason need to be able to call it like a->func(), you may be able to create thunks/trampolines that add in the argument.
Can't be done.
In C++ when you call member functions the compiler implicitly adds this as the first function argument. Mimicking obj->method() syntax in C won't work because there's no implicit this.
This doesn't mean that OO is impossible in C, simply that you can't use the same syntax as C++ or Java do to it. It can still be done, but you have to be explicit:
void * myFunc (void *this) {
...
}
a->func(a);
b->func(b);
Related
I'm probably getting mixed up as I'm a OO developer. I'm trying to have several instances that call a common method.
I want to somehow reference the caller in a function that is assigned thus...
header
typedef struct _Part Part;
struct _Part {
void (*move)();
}
code
void move(Part p) {
}
void main() {
Part part1;
part1.move = move(part1); <-- Won't compile
part1.move();
}
Is there some way of making this work or do I have to stop thinking like an OO dev and just call the move method directly, passing in the instance?
Declare the structure like
typedef struct _Part Part;
struct _Part {
void (*move)( Part);
};
and just write
part1.move = move;
The function designator is implicitly converted to a pointer to the function.
And then write
part1.move( part1 );
I have been struggling with function pointers for some time now. Maybe you guys can help me out.
In my project I have multiple functionalities for the same device and each functionality is written in its own .c file. The generic functionalities (which apply to all device functions) are written in generic.c.
I would like to create a function pointer array in the generic c file and fill that array in the other function files. So I can call the right function based on a device function identifier in the generic file.
What I have right now:
// in generic.h:
typedef void (*func_ptr_t[])(arguments);
extern func_ptr_t devFunctions[3];
And I would like to:
// in function1.c:
#include "generic.h"
devFunctions[1] = &functionName;
But then it complains about a type specifier missing AND the array initializer must be a list. If I add the type like
func_ptr_t devFunctions[1] = &functionName;
I get an error about an incomplete element type 'func_ptr_t'.
I can't initialize the entire array list from one file since it is filled from multiple files.
Anybody got an idea on how to tackle this?
Thanks!
-edit-
Because you can't use statements outside of functions I've changed my application. Now it does not use an array anymore and it updates the function pointer in the generic.c upon calling the specific function file.
So the end result:
In generic.h:
typedef void (*func_ptr_t)(<function arguments>)
In generic.c:
func_ptr_t devFunction;
In function1.c:
#include "generic.h"
extern func_ptr_t devFunction;
void functionToBeCalledFromMain( void ){
devFunction = functionName;
}
void functionName (void ){
// Function to be called from generic.c via function pointer
}
As most of you pointed out, filling the array is a statement which can't be put outside a function (duh...). So what I wanted is not really going to work in this case. I rewritten my application to update a function pointer (not an array anymore) on every run with the function I need. Saves a lot of trouble :)
Thanks guys!
For an example about functions of the type int f(int);, you can check :
/* function definition */
int functionName(int arg)
{
/* do things */
return arg * 2;
}
/* create the type "function pointer int->int" */
typedef int (*func_ptr_t)(int);
/* create the array */
func_ptr_t devFunctions[3];
int main(void)
{
/* associate the good function */
devFunctions[0] = &functionName;
/* call it with an arg */
return devFunctions[0](42);
}
Putting the above comments together, you probably wanted
typedef void (*func_ptr_t)(arg_type_list);
This question already has answers here:
How can I simulate OO-style polymorphism in C?
(13 answers)
Closed 6 years ago.
Suppose I have the following struct
struct Being{
int canFly;
int (*printFlying)();
}
And I want to do something like the following:
int main(){
struct Being * flyingThing = new_flyingThing();
struct Being * thingThatCantFly = new_Thing();
flyingThing->printFlying(); /* "I'm flying!" */
thingThatCantFly->printFlying(); /* "I can't fly!" */
}
It looks like I would need the printFlyingfunction to be able to access the canFly variable in the struct, but I don't know how to do this, or if this is possible.
Is there any way to get my code to do what I want? Thanks!!
I explained in the comments why this question is not a duplicate of the linked one.
C isn't an object-oriented language, so there's no automatic way for a function member to know which structure was used to call it.
Since each structure has its own function pointer, you can get the result you want by having them refer to different functions, which print the appropriate message, instead of getting it from the can_fly member.
int print_flying_thing() {
printf("I'm flying!\n");
}
struct Being *new_flyingThing() {
struct Being *thing = malloc(sizeof(struct Being));
thing->can_fly = 1;
thing->printFlying = print_flying_thing;
return thing;
}
int print_nonflying_thing() {
printf("I can't fly!\n");
}
struct Being *new_Thing() {
struct Being *thing = malloc(sizeof(struct Being));
thing->can_fly = 0;
thing->printFlying = print_nonflying_thing;
return thing;
}
The function pointed to by the printFlying pointer cannot access members of the containing struct Being structure unless it's given a parameter that refers to that structure. (Or it could access the structure in some other way, perhaps via a global variable, but a parameter is the cleanest way.)
Consider, for example, two objects of type struct Being, both having their printFlying pointer pointing to the same function. There's no way that function can tell which of the two objects it's associated with -- because it isn't associated with either of them.
C++ member functions can do that because they're given an implicit pointer parameter, referred to inside the function via the this keyword. C has no such feature.
You could probably create a macro that does something similar, but I doubt it would be worth the effort.
Have you considered just using C++?
For this particular example what you seem to really want is the ability to have a function pointer that points to two different functions, one to implement flying and one that implements not flying.
So the approach I would consider would be something like the following. I have not tried to actually compile this code but the sense of this is correct.
Also in your comments you mentioned about preventing changing the function pointer. You can do something like the following where a const is added to the struct definition for the function pointer and then using a clone of the struct with a cast.
Header file flying.h contents.
typedef struct _TAG_Being {
int (* const printFlying)();
} Being;
Being * new_flyingThing ();
Being * new_Thing();
Implementation or flying.c file.
#include "flying.h"
static int printFlyingThing()
{
printf (" I am a flying thing\n");
return 0;
}
static int printThing()
{
printf (" I am a thing\n");
return 1;
}
// use the same layout and members as Being above.
typedef struct {
int (* printFlying)();
} BeingX;
Being * new_flyingThing ()
{
BeingX *p = malloc(sizeof(BeingX));
p->printFlying = printFlyingThing; // use the flying thing function
{
Being *q = (Being *)p;
return q;
}
}
Being * new_Thing()
{
BeingX *p = malloc(sizeof(BeingX));
p->printFlying = printThing; // use the not flying thing function.
{
Being *q = (Being *)p;
return q;
}
}
Main or using .c file
#include "flying.h"
int main(){
Being * flyingThing = new_flyingThing();
Being * thingThatCantFly = new_Thing();
flyingThing->printFlying(); /* "I'm flying!" */
thingThatCantFly->printFlying(); /* "I can't fly!" */
}
If you have a need to access the actual Being object or variable in the printFlying() function then you will need to pass it as an argument.
For instance:
typedef struct _TAG_Being {
int xx;
int (*printFlying)(struct _TAG_Being *p);
} Being;
Then you would need something like:
Being * flyingThing = new_flyingThing();
flyingThing->printFlying(flyingThing); /* "I'm flying!" */
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
} struct1;
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
int struct_variable_2c;
} struct2;
typedef struct1 *struct1_ptr;
typedef struct2 *struct2_ptr;
static void sampleFunction(struct1_ptr valueToInsert){
//this code does some stuff here
}
int main(){
struct1_ptr struct1_var = (struct1_ptr) malloc(sizeof(struct1));
strcpy(struct1_var->struct_variable_1a, "some value");
strcpy(struct1_var->struct_variable_1b, "some value");
sampleFunction(struct1_var);
return 0;
}
I have a sample code in C programming as shown above. In the main method, I am trying to pass a variable of type struct1_ptr for sampleFunction method call.
This works like a charm. But when I want to pass a variable of type struct2_ptr, the compiler is throwing error. Basically, I am java developer. I want to reuse this sampleFunction method for any variable type in its parameter in general. Kindly help me in this.
You could emulate inheritance in C like this:
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
} struct1;
typedef struct
{
struct1 parent; /* Must be first element! */
int struct_variable_2c;
} struct2;
And then call like this:
sampleFunction((struct1_ptr)ptr_to_struct2);
or (I would favor this, because there's no cast):
sampleFunction(&ptr_to_struct2->parent);
Just note that you won't be able to access members of struct2 in function without casting it back.
These work for simple structures, but if you do anything more complex, using C++ would be more approriate.
unfortunately C does not support method overloading / polymorphism. So you have to write your own methodology.
one is, to give the type as a first parameter to every overloaded function. Inside the function you walk along with a simple switch-case to jump to the original function implementation (like struct1_sampleFunction() and struct2_sampleFunction()).
another is, to put an RECORDCORE struct at the beginning of every struct and fill the type into this RECORDCORE, so each function can dispatch according to this data.
in both cases you have to change the prototype from "struct1_ptr value" to "void *value"
change your function from:
static void sampleFunction(struct1_ptr valueToInsert){
//this code does some stuff here
}
to:
static void sampleFunction(void* valueToInsert){
//this code does some stuff here
}
If you want to identify the type of the structure add a second parameter to your function that contains the size of the struct.
//Edit:
Inside the function you have to cast your variable back to the structure you want to use. for example:
strcpy(((struct1_ptr)valueToInsert)->struct_variable_1a, "some value");
I am trying to understand the existing code.
When do we actually go for function pointers? specially like the one below.
struct xx
{
char *a;
(*func)(char *a, void *b);
void *b;
}
struct xx ppp[] = { };
then check sizeof(ppp)/sizeof(*ppp);
when do we go with such kind of approach?
sizeof array / sizeof *array is a way of finding out how many elements are in an array. (Note that it must be an array rather than a pointer.) I'm not sure how that's related to your function pointer question.
Function pointers are used to store a reference to a function so that it can be called later. The key thing is that a function pointer needn't always point to the same function. (If it did, you could just refer to the function by name.)
Here's an example based on your code (although I could provide a better one if I knew what your code was supposed to do.
char *s1 = "String one";
char *s2 = "String two";
void f(char *a, void *b) {
/* Do something with a and b */
}
void g(char *a, void *b) {
/* Do something else with a and b */
}
struct xx {
char *a;
void (*func)(char *a, void *b);
void *b;
}
struct xx ppp[] = { {s1, f, NULL}, {s2, g, NULL} };
int main(int argc, char **argv) {
for (int i = 0; i < (sizeof ppp / sizeof *ppp); i++) {
ppp[i].func(ppp[i].a, ppp[i].b);
}
}
There are two major uses (that I know of) for function pointers in C.
1. Callbacks
You have some sort of event-driven framework (a GUI is one of the easiest examples), and the program wants to react to events as they happen. Now you can do that with an event pump, like
while (event *e = get_one_event()) {
switch (e->type) {
case EVT_CLICK:
...
}
}
but that gets tiring after a while. The other major alternative is callbacks. The program defines a bunch of functions to handle different events, and then registers them with the library: "when event X happens, call function Y" -- so of course, the library is going to receive a function pointer, and call it at the relevant time.
2. Objects (function tables / vtables)
If you've done OO in most other languages, this should be fairly easy for you to picture. Imagine an object as a struct that contains its members and then a bunch of function pointers (or, maybe more likely, its members and a pointer to another struct representing its class, that contains a bunch of function pointers). The function pointers in the table are the object's methods. GLib/GObject is a big user of this technique, as is the Linux kernel (struct file_operations, struct device_driver, struct bus_type, and many many more). This lets us have an arbitrary number of objects with different behavior, without multiplying the amount of code.
When do we actually go for function pointers? specially like the one below.
You use function pointer when you want to make something more abstract.
By example, suppose your application has a graphical toolbox with a certain number of buttons. Every button corresponds to an instance of a certain struct.
The button structure can contain a function pointer and a context:
typedef struct {
void (*press_button) (void *context);
void *context;
/* Here some other stuff */
} Button;
When the user clicks the button, the event is something like
void event_click (Button *b)
{
b->press_button(b->context);
}
The point in doing this is that you can use always the same structure for each button:
Button * create_button (void (*callback) (void *), void *context, /* other params */
{
Button *ret = malloc(sizeof(Button));
if (ret != NULL) {
ret->callback = callback;
ret->context = context;
/* Assign other params */
}
...
return ret;
}
So when you build your toolbox you probably do something like
Button * toolbox[N];
toolbox[0] = create_button(function1, (void *)data, ...);
toolbox[1] = create_button(function2, (void *)something, ...);
...
toolbox[N-1] = create_button(functionN, (void *)something_else, ...);
Also when you create some function pointer, always carry some contxt information (like I did with the context field of the struct). This allows you to avoid global variables, thus you can get a robust and reentrant code!
Note:
This method is awesome, but if you deal with C++ you may prefer to use object orientation and replace callbacks with derivaton from abstract classes. By doing this you also don't need to carry the context, since the class will do it for you.
Edit in answer of first comment:
The current code I am going through is related to file IO. setting an environment variable and creating symbolic links between files, copying data from one file to another, etc. I am not understanding why do we need to call these functions at run time using function pointers. we can as well call them directly.
In fact you can do what you need without using function pointers. If I do understand well your problem, you are trying to understand someone else's code, which is doing what you listed with function pointers.
Personally I don't use this feature unless I need it but if you post here some additional code maybe we can try to understand it better.