繁体   English   中英

函数指针typedef在c中

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM