Reputation: 777
I'm trying to store a function pointer in a struct and can't make it works. Here's the code.
typedef enum { POUSSOIR, INTERRUPTEUR } Button_Type;
typedef struct Button {
char name[20];
Button_Type type;
void(*action)(struct Button*);
char input[20];
char output[20];
} Button;
static Button buttons[7];
Button Button_Create(char *name, Button_Type type, void (*action), char input[20], char output[20]) {
Button this;
strcpy(this.name, name);
this.type = type;
this.action = (*action)(&this);
strcpy(this.input, input);
strcpy(this.output, output);
return this;
}
void dimmer(Button *button) {
LOG("dim!!!");
}
int init_Buttons() {
buttons[0] = Button_Create("Salon", POUSSOIR, &dimmer, "DI04", "DMX_2");
return 1;
}
What I want is to have many buttons with differents callbacks for on-off case or dimmable case and more. So I wan't to init each button with a callback function. Also I can't pass the Button reference to Button_Create function as it doesn't exit yet. How can I acheive this ?
EDIT : SOLUTION
Button Button_Create(char *name, Button_Type type, void (*action)(Button*), char input[20], char output[20]) {
Button this;
strcpy(this.name, name);
this.type = type;
this.action = action;
strcpy(this.input, input);
strcpy(this.output, output);
return this;
}
//as example
void *fn_ButtonThread(void *p_Data) {
printf("Starting Button Thread.\r\n"); fflush(stdout);
while(!exitFlag) {
if (....) {
// Call the function with parameters here
buttons[0].action(&buttons[0]);
}
}
printf("Stopping Button Thread.\r\n"); fflush(stdout);
}
Upvotes: 0
Views: 68
Reputation: 955
Aren't the buttons created automatically by their declaration: static Button buttons[7]; They are not pointers, so that struct of 7 elements would be created. Also there are no system calls to CreateWindow etc.
Thus you can send &button[0] etc. as parameters to set their values. The code below compiles and prints "DI04" and "DMX_2", VS2019. (I haven't tested the function pointers).
typedef enum { POUSSOIR, INTERRUPTEUR } Button_Type;
typedef struct Button {
char name[20];
Button_Type type;
void(*action)(Button*);
char input[20];
char output[20];
} Button;
static Button buttons[7];
void LOG(const char* s) {
printf_s(s);
}
void Button_Create(Button &b, const char* name, Button_Type type, void(*action)(Button*), const char input[20], const char output[20]) {
//Button this;
strcpy_s(b.name, name);
b.type = type;
b.action = action; // (*action)(&b);
strcpy_s(b.input, input);
strcpy_s(b.output, output);
}
void dimmer(Button* button) {
LOG("dim!!!");
}
int init_Buttons() {
//buttons[0] = Button_Create("Salon", POUSSOIR, &dimmer, "DI04", "DMX_2");
Button_Create(buttons[0], "Salon", POUSSOIR, &dimmer, "DI04", "DMX_2");
printf_s(buttons[0].input);
printf_s("\n");
printf_s(buttons[0].output);
return 1;
}
int main()
{
init_Buttons();
return 0; //or whatever
}
enter code here
EDIT: (Button this; Ah plain C?... It's confusing with C++ this. Without references &:
void Button_Create_Ptr(Button *b, const char* name, Button_Type type, void(*action)(Button*), const char input[20], const char output[20]) {
//Button this;
strcpy_s(b->name, name);
b->type = type;
b->action = action; // (*action)(&b);
strcpy_s(b->input, input);
strcpy_s(b->output, output);
}
Then: Button_Create_Ptr(&buttons[1], "Baloon", POUSSOIR, &dimmer, "GYZ1", "BTS2");
Upvotes: 1
Reputation: 17403
The declaration of the action
parameter in Button_Create
and the setting of this.action
is wrong. Here is a corrected version:
Button Button_Create(char *name, Button_Type type, void (*action)(Button *), char input[20], char output[20]) {
Button this;
strcpy(this.name, name);
this.type = type;
this.action = action;
strcpy(this.input, input);
strcpy(this.output, output);
return this;
}
In the call to Button_Create
you can change &dimmer
to dimmer
. It will work either way because dimmer
is already considered to be a pointer to the function defined as dimmer
and the &
is ignored in this case. (Function pointers behave differently to object pointers in that regard.)
You could call a function defined as follows to invoke the action:
void Button_Press(Button *button) {
button->action(button);
}
Upvotes: 1