cjameston cjameston - 1 month ago 15
C Question

Function pointer typedef in c

I have some embedded OS functions that I need to simulate on a linux machine. The approach I've been instructed to take is to overload the embedded OS functions and wrap them around POSIX threads so the linux machine can handle the embedded OS functions during unit tests and whatnot.

The embedded OS function to create a new thread is:

OSCreateTask(OStypeTFP functionPointer, OSTypeTcbP taskId, OStypePrio priority)


I need to convert that
OStypeTFP
type into the void function pointer that
pthread_create
expects: (
void * (*)(void *)
is what the compiler tells me it's expecting)

I was hoping to create a typedef that I could use it like:

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);


but the compiler complains that
functionPointer
is of type
void (**)(void)
when pthread_create expects
void * (*)(void *)


Do I need to change my typedef somehow, or do I need to do some typecasting? Both?

Answer

You need an adapter function:

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);

Of course it is safe only if you system allows casts from void * to function pointer. But since we are at POSIX environment - it should be OK.

Comments