event
是一个类型,而不是一个对象或表达式。您不能访问结构类型的成员,只能访问结构类型的对象。
所以给出:
typedef struct {
void* fn;
void* param;
} event;
你需要有一个 type 的对象event
,并且你需要给它的成员赋值。
在您的问题中,您将fn
其用作成员名称,但随后您引用了名为function
. 我在这里假设它们应该是相同的东西,并且fn
应该指向某些功能。
您不能将函数指针可移植地存储在void*
. 在许多(可能是大多数)实现中,您可以摆脱它,但语言不能保证。(有些系统函数指针大于数据指针,将函数指针转换为void*
丢失信息。)另一方面,所有指向函数的类型都可以相互转换,并且保证往返转换给你原始的指针值。
我会假设(我在这里做了很多假设,因为您没有提供很多信息)您想要fn
指向一个接受void*
参数但不返回结果的函数;然后做param
一个void*
有意义的。为了与该假设保持一致,我们可以更改您的类型定义:
typedef struct {
void (*fn)(void*);
void *param;
} event;
(void (*fn)(void*);
语法并不完全明显。我曾经cdecl
构造它。)
现在您可以定义一个类型的对象event
:
event e = { some_func, NULL };
您必须在some_func
某处定义,如
void some_func(void *param { /* ... */ }
或同等学历。event
现在您可以通过对象间接调用该函数e
:
e.fn(e.param);
或者,如果有一个指向 a 的指针更方便event
:
event *ptr = malloc(sizeof *ptr);
if (event == NULL) {
/* error handling here */
}
ptr->fn = some_func;
ptr->param = NULL;
event
并且您可以在指向的指针和它指向的对象中包含的函数指针上使用间接event
:
ptr->fn(ptr->param);
根据您要完成的任务,您可能希望fn
能够指向不同类型的函数。如果这样做,则必须在通过它进行调用之前转换(使用显式转换)e.fn
或ptr->fn
它指向的函数的实际类型。不能盲目混用不同类型的函数指针;如果这样做,结果要么是编译时错误,要么是运行时未定义的行为。您可以将void (*)(void)
(指向不带参数且不返回结果的函数的指针)用作“通用”函数指针类型,但与void*
任何类型的转换不同,您需要的类型必须是显式的。)
我想知道如何在使用和不使用附加void*
参数的情况下进行函数调用。
要调用不带参数的函数,只需()
在函数调用中使用。但是同样,对于给定的函数,您不能选择使用或不使用参数来调用它;调用必须与定义匹配。(除了可能的可变参数函数printf
,但您仍然需要一个正确类型的函数指针,并且不能在没有参数的情况下调用可变参数函数。)