【问题标题】:How to use lambda functions or std::function with an API that takes function pointers?如何使用带有函数指针的 API 的 lambda 函数或 std::function?
【发布时间】:2014-04-06 14:47:33
【问题描述】:

假设我想在 pthreads 上实现一个简单的抽象。 (或任何为回调或线程获取函数指针的 C API)。

像 std::thread 一样,我希望接口能够接受一般的函数对象。

如何以适用于所有情况的方式弥合差距? (包括绑定、lambda 函数等)

我知道 std::function::target ,但是 afaik,它不能满足我的需要。

【问题讨论】:

  • 函数指针是否接受参数(void* userData)?
  • 不一定,但我认为硬编码特定实例的参数类型是可以接受的。不过,如果可能的话,模板版本会更好。
  • std::function::target() 不做你想做的事吗?

标签: c++ linux multithreading


【解决方案1】:

如果 API 将带有 void* 的函数用于用户数据,例如 pthread_create(),您需要将指向该函数的指针作为用户数据传递,调用一个将用户数据转换为您的函数类型的蹦床, 并调用函数。例如:

#include <functional>
#include <pthread.h>

extern "C" void* trampoline(void* userData) {
    return (*static_cast<std::function<void*()>*>(userData))();
}

void* start() {
    // ...
    return 0;
}

int main() {
    pthread_t thread;
    std::function<void*()> entry(start);
    pthread_create(&thread, 0, &trampoline, &entry);
    // ...
}

然而,直接的含义是函数对象的生命周期不容易控制。在上面的示例中,std::function&lt;void*()&gt; 对象的寿命恰好足够长,但并不总是那么容易。

如果您尝试调用的函数没有用户数据参数,那么您很不走运。使用全局对象可能会侥幸成功,但几乎可以肯定这是一种相当脆弱的方法。

【讨论】:

    【解决方案2】:

    lambda 函数可以在任何需要常规函数指针的地方使用。换句话说,它可以在任何使用常规函数/指向函数的指针的地方使用..

    示例:https://ideone.com/4CJjlL

    #include <iostream>
    
    void voidfunc(void (*func_ptr)(void))
    {
        func_ptr();
    }
    
    void funcwithargs(void (*func_ptr)(int, char, std::string), int a, char b, std::string c)
    {
        func_ptr(a, b, c);
    }
    
    int main()
    {
        auto vf = []{std::cout<<"Called void func..\n";};
        auto vfwa = [](int a, char b, std::string c) {std::cout<<"Called func with args with: "<<a<<b<<" "<<c<<"\n";};
    
        voidfunc(vf);
        funcwithargs(vfwa, 10, 'x', " + 3");
        return 0;
    }
    

    同样,您可以使用std::function 代替函数指针..

    【讨论】:

    • 哦,你是对的,我没有注意到.. 我猜你不能在有 func ptr 的地方使用 std::function 但你可以在有 @ 的地方使用 func ptr's 或 lambdas 987654325@..我现在明白了..
    猜你喜欢
    • 1970-01-01
    • 2011-06-13
    • 2016-04-02
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2017-08-27
    • 1970-01-01
    相关资源
    最近更新 更多