C++ “Dynamic” function pointers for C callback functions

前端 未结 2 1152
生来不讨喜
生来不讨喜 2021-01-18 21:44

I have an API for managing a camera configuration. There are 344 individual options to manage. When a certain value changes the API calls a callback function to notify the p

2条回答
  •  广开言路
    2021-01-18 22:13

    You can generate closures dynamically using libffi. These are regular function pointers that can retain one pointer to user data, in this case the callback number.

    #include 
    #include 
    #include "ffi.h"
    
    using namespace std;
    void the_callback(size_t num, void* arg) {
        cout << "This is callback #" << num << " with argument " << hex << arg << endl;
    }
    
    void generic_cb(ffi_cif *cif, void *ret, void **args, void *user_data) {
        the_callback((size_t) user_data, *(void **)args[0]);
    }
    
    typedef void (*Callback)(void*);
    
    ffi_cif callback_cif;
    int main() {
        ffi_type *argtypes[] = { &ffi_type_pointer };
        ffi_status st = ffi_prep_cif(&callback_cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, argtypes);
    
        std::vector callbacks;
        for (size_t i = 0; i < 100; i++) {
            void *cb;
            ffi_closure *writable = (ffi_closure*)ffi_closure_alloc(sizeof(ffi_closure), &cb);
            st = ffi_prep_closure_loc(writable, &callback_cif, generic_cb, (void*)i, cb);
            callbacks.push_back((Callback)cb);
        }
    
        callbacks[13]((void*)0xabcdef);
        callbacks[87]((void*)0x1234);
    }
    

    This produces the following output:

    This is callback #13 with argument 0xabcdef
    This is callback #57 with argument 0x1234
    

提交回复
热议问题