I have a struct that has a element in it denoted as void (*func)(); I know that void pointers are usually used for function pointers but I cannot seem to define the function. I keep getting dereferencing pointer to incomplete type. I googled around but to no avail. Any advice would be appreciated.
I am trying to do this:
struct callback * cb;
cb->func = *readUserInput;
ReadUserInput is defined as:
void readUserInput(void)
{
}
And Callback is defined as such:
struct callback {
void (*func)();
int pcount;
enum attr_type type;
void *p[0];
};
You need to take the address of the function, not attempt to dereference it.
Change
cb->func = *readUserInput;
to
cb->func = &readUserInput;
Also, you are creating a pointer that has a garbage value and then dereferencing it, causing undefined behaviour. You need to allocate space for it one way or another (malloc/free or just allocate it on the stack):
struct callback cb; // put it on the stack
cb.func = &readUserInput;
or
struct callback * cb = malloc(sizeof(callback));
cb->func = &readUserInput;
...
free(cb);
You have three problems.
Your syntax when assigning the function pointer is incorrect, and you're not actually defining an instance of struct callback.
You want to say:
struct callback cb;
cb.func = readUserInput;
You could explicitly take the address of the readUserInput function, but it is unnecessary. That syntax would look like:
struct callback cb;
cb.func = &readUserInput;
In standard C, a bare function name will be evaluated as the address of the function.
Finally, your callback has the wrong signature. It's defined as a function taking an unknown number of arguments and returning nothing.
Your declaration in the struct calls for a pointer to a function taking no arguments and returning nothing.
Define the callback function as:
void readUserInput()
{
}
or correct the declaration in the struct as:
struct callback {
void (*func)(void);
int pcount;
enum attr_type type;
void *p[0];
};
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 );
In the firmware that I am writing, I created a type of variable. Similar to what is below:
struct SitemMenu {
unsigned int id;
char * text;
void * submenu
}
typedef struct SitemMenu TitemMenu;
Be any function:
void functionX () {
...
}
If I create this variable:
TitemMenu itemWhatever;
and do:
itemWhatever.submenu = &function (X);
Can I call functionX doing:
(*itemWhatever.submenu)();
I did something similar to this and the compiler give this answer:
error: (183) function or function pointer required
Yes you can, but not quite the way you've written it.
A function pointer is not declared in quite the same way as a 'normal' pointer.
What you need is:
struct SitemMenu {
unsigned int id;
char * text;
void (* submenu)(void); // this is a function pointer, as opposed to the 'normal' pointer above
};
typedef struct SitemMenu TitemMenu;
TitemMenu itemWhatever;
then, if you have some function declared with the same parameters and return type, like:
void functionX(), then you can do:
itemWhatever.submenu = functionX;
itemWhatever.submenu();
I am learning C and trying to pass structure to call back function. Gone through online resources but unable to pass structure to call back function. Here is my code.
// myvariables.h
struct callbackStruct
{
int a;
int b;
int c;
};
extern struct callbackStruct callbackStructObject;
typedef void (*callback)(struct callbackStruct);
extern void callback_reg(callback pointerRefCallback);
// Operations.c
struct callbackStruct callbackStructObject;
void callback_reg(callback pointerRefCallback) {
(*pointerRefCallback)(callbackStructObject);
}
// main.c
struct callbackStruct myCallbackStruct1;
void my_callback(struct callbackStruct myCallbackStruct) {
printf("A value:%d" + myCallbackStruct.a);
}
int main()
{
callback ptr_my_callback = my_callback(myCallbackStruct1);
callback_reg(ptr_my_callback);
return 0;
}
Can anyone resolve this scenario?
The type callback is a function pointer type, e.g. a variable of that type is a pointer that points to a function that accepts a struct callbackStruct as single parameter:
typedef void (*callback)(struct callbackStruct);
So when you write (in main):
// ...
callback ptr_my_callback = // HERE
// ...
The expression at HERE must be the address of a function with the correct signature. You write:
my_callback(myCallbackStruct1);
Since my_callback is a function that returns nothing (void) and the above expression calls this function, the expression
callback ptr_my_callback = my_callback(yCallbackStruct1);
is not well formed (syntactically, as well as from the perspective of the type system).
Assuming that my_callback is the function that you want to work as a callback, you need to store its address in the pointer ptr_my_callback:
callback ptr_my_callback = &my_callback;
It's kind of unclear what your code is supposed to achieve, though, so I cannot really help you any further.
I want to create a C module which handles Callbacks:
typedef struct {
int enable;
void (*callback)(void);
void *obj;
} Callback;
void Callback_Notify(Callback *me) {
if (me->enable && me->callback) me->callback(me->obj);
}
However, the modules which shall use this Callback module have callbacks with (different) parameters. My current solution is a preprocessor hack (left out the \):
#define Callback_Notify1Arg(me, cb_type, arg1)
if (me->enable && me->callback)
((cb_type)me->callback)(me->obj, arg1);
#define Callback_Notify2Arg(me, cb_type, arg1, arg2)
if (me->enable && me->callback)
((cb_type)me->callback)(me->obj, arg1, arg2);
Now a module using the Callback looks like the following:
typedef void (*SomeModuleCb_t)(int);
typedef struct { Callback cb; } SomeModule;
void SomeModule_DoSomething(SomeModule *me) {
int someData;
Callback_Notify1Arg((&me->cb), SomeModuleCb_t, someData);
}
The Code works! But I want to know if there is a stack corruption? Does the compiler allocate/deallocate the stack correctly around the Callback usage in SomeModule_DoSomething? For the memory allocation in the Callback struct does the callback pointer's signature matter?
Any better solutions for the topic are welcome!
Thanks for the clarification!
As long as the function pointer was to a function that accepts that parameters, and you cast the function pointer to the original type there shouldn't be a problem. You can cast a function pointer to another function pointer if you cast to the original type before doing the call.
I have two functions, each taking a pointer to a different type:
void processA(A *);
void processB(B *);
Is there a function pointer type that would be able to hold a pointer to either function without casting?
I tried to use
typedef void(*processor_t)(void*);
processor_t Ps[] = {processA, processB};
but it didn't work (compiler complains about incompatible pointer initialization).
Edit: Another part of code would iterate through the entries of Ps, without knowing the types. This code would be passing a char* as a parameter. Like this:
Ps[i](data_pointers[j]);
Edit: Thanks everyone. In the end, I will probably use something like this:
void processA(void*);
void processB(void*);
typedef void(*processor_t)(void*);
processor_t Ps[] = {processA, processB};
...
void processA(void *arg)
{
A *data = arg;
...
}
If you typedef void (*processor_t)(); then this will compile in C. This is because an empty argument list leaves the number and types of arguments to a function unspecified, so this typedef just defines a type which is "pointer to function returning void, taking an unspecified number of arguments of unspecified type."
Edit: Incidentally, you don't need the ampersands in front of the function names in the initializer list. In C, a function name in that context decays to a pointer to the function.
It works if you cast them
processor_t Ps[] = {(processor_t)processA, (processor_t)processB};
By the way, if your code is ridden with this type of things and switch's all over the place to figure out which function you need to call, you might want to take a look at object oriented programming. I personally don't like it much (especially C++...), but it does make a good job removing this kind of code with virtual inheritance.
This can be done without casts by using a union:
typedef struct A A;
typedef struct B B;
void processA(A *);
void processB(B *);
typedef union { void (*A)(A *); void (*B)(B *); } U;
U Ps[] = { {.A = processA}, {.B = processB} };
int main(void)
{
Ps[0].A(0); // 0 used for example; normally you would supply a pointer to an A.
Ps[1].B(0); // 0 used for example; normally you would supply a pointer to a B.
return 0;
}
You must call the function using the correct member name; this method only allows you to store one pointer or the other in each array element, not to perform weird function aliasing.
Another alternative is to use proxy functions that do have the type needed when calling with a parameter that is a pointer to char and that call the actual function with its proper type:
typedef struct A A;
typedef struct B B;
void processA(A *);
void processB(B *);
typedef void (*processor_t)();
void processAproxy(char *A) { processA(A); }
void processBproxy(char *B) { processB(B); }
processor_t Ps[] = { processAproxy, processBproxy };
int main(void)
{
char *a = (char *) address of some A object;
char *b = (char *) address of some B object;
Ps[0](a);
Ps[1](b);
return 0;
}
I used char * above since you stated you are using it, but I would generally prefer void *.