简体   繁体   中英

std::function to C-style function pointer

I'm using a library written in C. This library accepts callbacks like this:

int(*)(int arg, void* user_param)

Is it possible to create a std::function<int(int, void*)> and pass it to this library as a callback?

I know that std::function has a target method which returns the address of the stored function, but as far as I know it can't return the address if its holding a lambda expression. Or am I wrong?

You can use lambda functions with C-style function pointers, just not using std::function .

Lambdas that don't have any capture are convertible to a functions pointer:

using callback_t = int(*)(int arg, void* user_param);
void set_c_callback(callback_t, void* user_param);

// ...

void foo() {
    set_c_callback([](int a, void* data) {
        // code
    }, nullptr);
}

But there is also a way with lambda with captures, using std::any :

// The storage can be inside a class instead of a global
std::any lambda_storage;

template<typename T>
void foo(T lambda) {
    lambda_storage = lambda;
    set_c_callback([](int n, void* user_data) {
        auto& lambda = *std::any_cast<T>(static_cast<std::any*>(user_data));
        lambda(n);
    }, &lambda_storage)
}

// ...

foo([k = 1](int n) {
    std::cout << n + k << std::endl;
});

If you want to pass a lambda to the C library, you should be able to, as long as the lambda has no captures. A captureless lambda can be implicitly converted to a function pointer, so simply setting it as a callback should work.

Passing a lambda that uses captures (or eg an std::function ) will not work, since they can't be converted to "plain" function pointers, because they hold an internal state.

std::function cannot be used where a C-style function pointer is expected.

A non-capturing lambda can (but a capturing lambda cannot).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM