Могу ли я сначала выделить структуру (с функцией внутри) для void* и запустить функцию внутри нее.
struct func {
void (*fp)(); // this is a function
};
struct thread{
void *stack; // I'm gonna use this to store 'struct func' above
};
void assign(struct thread *t,void *f()){
struct func *task = (struct func *)malloc(sizeof(struct func));
task->fp = f;
t->stack = task;
// question: now I want to call the function inside func and deeper inside void*
// I mean: trigger the function fp()
t->stack->fp(); // error here
}





Член stack имеет тип void * и поэтому не может быть разыменован как есть.
Сначала вам нужно будет привести его к правильному типу указателя (или назначить указателю этого типа) перед разыменованием.
((struct func *)t->stack)->fp();
// or
struct func *f = t->stack;
f->fp();
Проблему можно полностью избежать, если использовать «правильныеTM» типы данных:
#include <stdlib.h>
struct func {
void (*fp)();
};
struct thread {
struct func *stack;
};
void assign(struct thread *t, void (*f)()) {
struct func *task = malloc(sizeof *task);
task->fp = f;
t->stack = task;
}
void call(const struct thread *t) {
t->stack->fp();
}
/* --- usage example --- */
#include <stdio.h>
void f(void) {
puts("f() called.");
}
int main(void) {
struct thread t;
assign(&t, f);
call(&t);
}
Примечания:
malloc(), это на самом деле запах кода.sizeof позволяет избежать опечаток при изменении типа данных.f не был указателем на функцию. Вам нужен набор круглых скобок.void, как в void (*fp)(void).struct func {
void (*fp)(); // this is a function
};
Это не функция. Это просто указатель на функцию, которая возвращает void. Если вы хотите, чтобы он не использовал аргументов, заявите об этом (fp)(void)
«Могу ли я сначала выделить структуру (с функцией внутри) для void* и запустить функцию внутри нее?»
Да, ты можешь.
Ниже приведен общий способ написания подобных вещей.
Обычно typedef эти вещи обозначают для удобства, например:
typedef void(Function)(void);
typedef struct
{
void* fp;
// other stuff
} Container;
Container* so_create_c(Function*);
Container* so_delete_c(Container*);
int assign_f_to_c(Function*, Container*);
typedef struct
{
Container* stack;
// other stuff
} Thread;
void f1(void);
void f2(void);
В Containerfp может быть просто Function*, но вы просили void* в вопросе. Использование void* означает, что в момент вызова fp следует привести к Function*, как в
((Function*)t1.stack->fp)();
См. пример кода ниже.
no function in Thread!
hi from f1
***** hi from f2! *****
***** hi from f2! *****
#include <stdio.h>
#include <stdlib.h>
typedef void(Function)(void);
typedef struct
{
void* fp;
// other stuff
} Container;
Container* so_create_c(Function*);
Container* so_delete_c(Container*);
int assign_f_to_c(Function*, Container*);
typedef struct
{
Container* stack;
// other stuff
} Thread;
void f1(void);
void f2(void);
int main(void)
{
Container* c1 = so_create_c(NULL);
Container* c2 = so_create_c(f2);
Thread t1 = {.stack = c1};
// c1 has no function yet
if ((t1.stack != NULL) && (t1.stack->fp != NULL))
((Function*)t1.stack->fp)();
else
fprintf(stderr, "no function in Thread!\n");
assign_f_to_c(f1, c1);
// now c1 points to a function
if ((t1.stack != NULL) && (t1.stack->fp != NULL))
((Function*)t1.stack->fp)();
else
fprintf(stderr, "no function in Thread!\n");
// c2 points to f2...
((Function*)c2->fp)();
t1.stack = c2; // now t1 points to c2 that points to f2
if ((t1.stack != NULL) && (t1.stack->fp != NULL))
((Function*)t1.stack->fp)();
else
fprintf(stderr, "no function in Thread!\n");
so_delete_c(c1);
so_delete_c(c2);
return 0;
}
Container* so_create_c(Function* p)
{
Container* container =
(Container*)malloc(sizeof(Container));
if (container == NULL) return NULL;
container->fp = p;
return container;
}
Container* so_delete_c(Container* c)
{
if (c == NULL) return NULL;
free(c);
return NULL;
}
int assign_f_to_c(Function* pF, Container* c)
{
if (pF == NULL) return -1;
if (c == NULL) return -2;
c->fp = pF;
return 0;
}
void f1(void) { printf("hi from f1\n"); }
void f2(void) { printf("***** hi from f2! *****\n"); }
// https://stackoverflow.com/questions/78164360/call-a-function-inside-struct-but-struct-inside-a-void