如何使用带有函数指针的API的lambda函数或std :: function?

时间:2014-04-06 14:47:33

标签: c++ linux multithreading

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

与std :: thread一样,我希望接口能够通常使用函数对象。

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

我知道std :: function :: target但afaik,它没有做我需要的。

2 个答案:

答案 0 :(得分:0)

如果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<void*()>对象碰巧活得足够长,但并不总是那么容易。

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

答案 1 :(得分:0)

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代替函数指针..