How to use a std::function as a C style callback

10,273

Solution 1

Long answer: sort of. You can write a C function to pass to the API that calls your std::function:

// --- some C code I can not change ---
typedef void(*fun)(int);
void register_callback(fun f) {
    f(42); // a test
}
// ------------------------------------

#include <functional>
#include <iostream>

void foo(const char* ptr, int v, float x) {
    std::cout << ptr << " " << v << " " << x << std::endl;
}

namespace {
std::function<void(int)> callback;
extern "C" void wrapper(int i) {
    callback(i);
}
}

int main() {
    callback = std::bind(&foo, "test", std::placeholders::_1, 3.f);
    register_callback(wrapper); // <-- How to do this?
}

Solution 2

In most cases you can't.

But when you store a C style callback in your std::function, you can use the target() member function.

Share:
10,273

Related videos on Youtube

Danvil
Author by

Danvil

I am a post doctoral student at the TUM in Munich, Germany.

Updated on September 15, 2022

Comments

  • Danvil
    Danvil over 1 year

    How can I use a std::function in a function which expects a C-style callback?

    If this is not possible, what is the next best thing?

    Example:

    // --- some C code I can not change ---
    typedef void(*fun)(int);
    void register_callback(fun f) {
        f(42); // a test
    }
    // ------------------------------------
    
    #include <functional>
    #include <iostream>
    
    void foo(const char* ptr, int v, float x) {
        std::cout << ptr << " " << v << " " << x << std::endl;
    }
    
    int main() {
        std::function<void(int)> myf = std::bind(&foo, "test", std::placeholders::_1, 3.f);
        register_callback(myf); // <-- How to do this?
    }
    
    • Mike Seymour
      Mike Seymour over 10 years
      Short answer: you can't.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 10 years
    Hey, nice - I didn't know about this.