[英]Function pointer typedef in c
我有一些嵌入式操作系统功能,我需要在linux机器上进行模拟。 我被指示采取的方法是重载嵌入式操作系统功能并将它们包装在POSIX线程中,以便linux机器可以在单元测试期间处理嵌入式操作系统功能等等。
用于创建新线程的嵌入式OS函数是: OSCreateTask(OStypeTFP functionPointer, OSTypeTcbP taskId, OStypePrio priority)
我需要将该OStypeTFP
类型转换为pthread_create
期望的void函数指针:( void * (*)(void *)
是编译器告诉我的预期)
我希望创建一个我可以使用它的typedef:
typedef void (*OStypeTFP)(void);
// Function to run task/thread in
void taskFunction(void) { while(1); }
// Overloaded Embedded OS function
void OSCreateTask(OStypeTFP tFP, OStypeTcbP tcbP, OStypePrio prio)
{
pthread_attr_t threadAttrs;
pthread_t thread;
pthread_attr_init(&threadAttributes);
pthread_create(&thread, &threadAttributes, &tFP, NULL);
}
// Creates a task that runs in taskFunction
OSCreateTask (taskFunction, id, prio);
但是当pthread_create期望void * (*)(void *)
时,编译器会抱怨functionPointer
的类型为void (**)(void)
void * (*)(void *)
我是否需要以某种方式更改我的typedef,还是需要进行类型转换? 都?
你需要一个适配器功能:
typedef void (*OStypeTFP)(void);
// Function to run task/thread in
void taskFunction(void) { while(1); }
void *trampoline(void *arg)
{
OStypeTFP task = (OStypeTFP)arg;
task();
return NULL;
}
// Overloaded Embedded OS function
void OSCreateTask(OStypeTFP tFP, OStypeTcbP tcbP, OStypePrio prio)
{
pthread_attr_t threadAttrs;
pthread_t thread;
pthread_attr_init(&threadAttrs);
pthread_create(&thread, &threadAttrs, trampoline, tFP);
}
// Creates a task that runs in taskFunction
OSCreateTask (taskFunction, id, prio);
当然,只有当系统允许从void *
转换为函数指针时,它才是安全的。 但由于我们处于POSIX环境 - 它应该没问题。
如果我理解正确,嵌入式操作系统上的线程过程的签名是void thread_proc(void)
。 另一方面,对于POSIX线程,它是void *thread_proc(void *)
。
你不能用casts和typedef来解释这种差异:你需要安排一个合适的返回值。 你需要一个垫片功能:
typedef void (*OStypeTFP)(void);
struct emu_OSCreateTask_thread_start_data
{
OStypeTFP real_thread_proc;
// possibly other stuff
};
void *emu_OSCreateTask_shim_thread_proc (void *xctx)
{
struct emu_OSCreateTask_thread_start_data *ctx = xctx;
ctx->real_thread_proc();
return 0;
}
void OSCreateTask(OStypeTFP tFP, OStypeTcbP tcbP, OStypePrio prio)
{
pthread_attr_t threadAttrs;
pthread_t thread;
struct emu_OSCreateTask_thread_start_data *ctx =
malloc(sizeof(struct emu_OSCreateTask_thread_start_data));
ctx->real_thread_proc = tFP;
pthread_attr_init(&threadAttributes);
pthread_create(&thread, &threadAttributes,
emu_OSCreateTask_shim_thread_proc, ctx);
}
注意: ctx
在堆上分配并泄漏,因为它需要存在直到emu_OSCreateTask_shim_thread_proc
返回之后,这可能比OSCreateTask
返回的时间晚。 如果你不了解你想要模仿的API的更多信息,我不能告诉你应该在哪里存储它以便它可以在适当的时候被释放,但可能在某个地方 。 也许在tcbP
?
注意2:我使用上下文对象而不是在pthread_create
的上下文指针中填充“ real_thread_proc
”(如在Sergio的答案中),因为我怀疑你最终需要在垫片中做更多的东西,并且需要更多的数据来自这样做的外在背景。 (您在POSIX系统上,因此将函数指针填充到void *
是安全的。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.