类型转换无效*(*)(无效*)为void(*)(无效) [英] Type cast void*(*)(void*) to void(*)(void)

查看:1060
本文介绍了类型转换无效*(*)(无效*)为void(*)(无效)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为转让的一部分,我想创建一个用户级线程库的pthreads一样。

As a part of an assignment, I am trying to create a user level thread library like pthreads.

有关处理的背景线程之间进行切换,我使用'swapcontext功能。使用它之前,我必须要使用makecontext功能的上下文。 makecontext期待与返回类型的函数指针无效和参数类型(无效)

For handling the context switching between the threads, I am using 'swapcontext' function. Before using it I have to make a context using 'makecontext' function. 'makecontext' expects a function pointer with return type void and argument type (void).

然而,线程函数必须是类型无效* thread_func(无效*)

Whereas, the thread function has to be of the type void* thread_func (void*)

有没有办法做一个类型转换?或者是有一些其他的方式来进行上下文在用户级别切换?

Is there a way to do a typecasting? Or is there some other way to do context switching at the user level?

推荐答案

这是非法的函数的地址转换为不同的原型,并通过所产生的指针调用它来调用不兼容的原型的函数:

It is illegal to invoke a function with an incompatible prototype by casting the address of the function to a different prototype and invoking it through the resulting pointer:

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

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

你可以做的是传递给 makecontext 您自己的回调,这将调用 thread_func 并忽略它的返回值。一个小功能仅用于调用另一个功能是有时称为蹦床

What you can do is pass to makecontext your own callback which will call thread_func and ignore its return value. A small function that only serves to call another function is sometimes called a 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);
  ...
}

有关奖励积分,您可以修改蹦床存储由回调函数栈上返回的无效* 的价值和你的的等价在pthread_join()检索。

For bonus points, you can modify the trampoline to store the void * value returned by the callback function on the stack and have your equivalent of pthread_join() retrieve it.

这篇关于类型转换无效*(*)(无效*)为void(*)(无效)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆