【问题标题】:How to assign a function to a function pointer that takes argument of type void*?如何将函数分配给接受 void* 类型参数的函数指针?
【发布时间】:2016-02-20 10:36:28
【问题描述】:

我正在使用我的教授提供的库来完成课堂作业,因此我不能透露太多我的代码。以下是 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 呢?如何将函数分配给函数指针?

【问题讨论】:

    标签: c++ void-pointers


    【解决方案1】:

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

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

    更改函数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++ 代码。

    【讨论】:

      【解决方案2】:

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

      因为这个说法不正确。在 C++ 中,您必须为此使用强制转换。这是 C++ 和 C 之间的一大区别。另请参阅 Difference between void pointers in C and C++

      你可以测试一下。将您的代码编译为 C,删除像 &lt;iostream&gt; 这样的 C++ 功能,它应该可以按预期工作。

      如何分配 函数指向函数指针?

      pHello的签名改为:

      void pHello(void*)
      

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

      另外,当您调用thread_libinit 时,第二个参数必须是int 对象的地址,该对象在函数返回之前一直存在。


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

      【讨论】:

      • 很好,您添加了(几乎可以肯定)猜测为什么会发生此错误,+1。
      猜你喜欢
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 2013-06-06
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      相关资源
      最近更新 更多