User98
User98

Reputation: 31

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?

Upvotes: 1

Views: 1424

Answers (3)

Guillaume Racicot
Guillaume Racicot

Reputation: 41750

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;
});

Upvotes: 2

Remy Lebeau
Remy Lebeau

Reputation: 595557

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

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

Upvotes: 0

AVH
AVH

Reputation: 11506

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 e.g. an std::function) will not work, since they can't be converted to "plain" function pointers, because they hold an internal state.

Upvotes: 0

Related Questions