c - 将 void*(*)(void*) 类型转换为 void(*)(void)

标签 c multithreading casting pthreads

作为作业的一部分,我正在尝试创建一个用户级线程库,如 pthreads。

为了处理线程之间的上下文切换,我使用了“swapcontext”函数。在使用它之前,我必须使用“makecontext”函数创建一个上下文。 “makecontext”需要一个返回类型为 void 和参数类型为 (void) 的函数指针。

而线程函数的类型必须是 void* thread_func (void*)

有没有办法进行类型转换?或者是否有其他方法可以在用户级别进行上下文切换?

最佳答案

通过将函数的地址转换为不同的原型(prototype)并通过结果指针调用它来调用具有不兼容原型(prototype)的函数是非法的:

void *my_callback(void *arg) { ... }

void (*broken)(void *) = (void (*)(void *)) my_callback;
broken(some_arg);   // incorrect, my_callback returns a `void *`

您可以做的是将您自己的回调传递给 makecontext,它将调用 thread_func 并忽略其返回值。仅用于调用另一个函数的小函数有时称为 trampoline。 .

/* return type is compatible with the prototype of the callback received
   by makecontext; simply calls the real callback */
static void trampoline(int cb, int arg)
{
  void *(*real_cb)(void *) = (void *(*)(void *)) cb;
  void *real_arg = arg;
  real_cb(real_arg);
}

int my_pthread_create(void *(*cb)(void *), void *arg)
{
  ucontext_t *ucp;
  ...
  /* For brevity treating `void *` as the same size as `int` -
     DO NOT USE AS-IS.
     makecontext exposes an annoyingly inconvenient API that only
     accepts int arguments; correct code would deconstruct each
     pointer into two ints (on architectures where pointer is
     larger than int) and reconstruct them in the trampoline. */
  makecontext(ucp, trampoline, 2, (int) cb, (int) arg);
  ...
}

对于奖励积分,您可以修改蹦床以将回调函数返回的 void * 值存储在堆栈上,并让您的 pthread_join() 检索它.

关于c - 将 void*(*)(void*) 类型转换为 void(*)(void),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14530109/

相关文章:

c# - 在 C# 中使用 C 结构体

c++ - 如何使用 QProcess 通过 Ping 检测 "Network is Unreachable"?

c - 什么时候函数会加载到内存中?

c - 关于链表结构语法的问题

Python 线程堆栈大小和段错误

java - 使用线程

casting - Kotlin合成整数不能转换为 float 按钮

c# - .Net框架如何实现int到float的转换?

c++ - QThread:如何使用 protected 静态函数

Java float 到 long 显式转换