如何将函数赋值给带有void *类型参数的函数指针?

时间:2016-02-20 10:36:29

标签: c++ void-pointers

我正在使用我教授提供的图书馆进行课堂作业,所以我无法透露太多的代码。以下是API的一部分:

typedef void (*thread_startfunc_t) (void*); 
int thread_libinit(thread_startfunc_t func, void *arg);
int thread_create(thread_startfunc_t func, void *arg);

 thread_libinit initializes the thread library.  A user program should call
 thread_libinit exactly once (before calling any other thread functions).
 thread_libinit creates and runs the first thread.  This first thread is
 initialized to call the function pointed to by func with the single
 argument arg.  Note that a successful call to thread_libinit will not
 return to the calling function.  Instead, control transfers to func, and
 the function that calls thread_libinit will never execute again.

 thread_create is used to create a new thread.  When the newly created
 thread starts, it will call the function pointed to by func and pass it the
 single argument arg.

为了测试,我编写了以下代码:

void pHello(int i)
{
   cout << "Hello from thread " << i << endl;
}

... [In Main] ...

typedef void (*thread_startfunc_t) (void* i); 
thread_startfunc_t pSalute = & pHello; //Does not compile

thread_libinit(pSalute,1); 

我收到错误:

In function `int main(int, char**)`: 
error: invalid conversion from `void (*) (int)' to `thread_startfunc_t{aka void(*) (void*)}' [-fpermissive]

我认为void指针变量可以指向任何变量。那么为什么它不能指向pHello函数的int?如何为函数指针赋值?

2 个答案:

答案 0 :(得分:2)

具有特定签名的函数指针(作为返回类型和变量类型给出)只能指向具有相同签名的函数。

在您的情况下,似乎您无法更改函数指针类型,您可以根据

更改函数pHello
void pHello(void* i)
{
   std::cout << "Hello from thread " << *static_cast<int*>(i) << std::endl;
}

typedef void (*thread_startfunc_t) (void*);

int main()
{
    thread_startfunc_t f = pHello;

    //or point to a non-capturing lambda:
    thread_startfunc_t f2 = [](void *) { std::cout<<"hi"<<std::endl; };
}

然而,这不是很好的C ++代码。

答案 1 :(得分:1)

  

我认为void指针变量可以指向任何变量。所以为什么   它能指向pHello函数的int吗?

因为声明不正确。在C ++中,您必须使用强制转换。这是C ++和C之间的巨大差异之一。另请参阅Difference between void pointers in C and C++

你可以测试一下。将代码编译为C,删除Cmd + w 等C ++功能,它应该按预期工作。

  

如何指定   函数指针的函数?

Cmd + w的签名更改为:

<iostream>

在函数内部,必须使用强制转换来获取指针对象的值。

此外,当您调用pHello时,第二个参数必须是void pHello(void*) 对象的地址,该对象一直存在,直到函数返回。

当然,这些都不是很好或现代的C ++。您的教授的API应该使用thread_libinit