1

I got segmentation fault for following code.

#include <iostream>
#include <functional>

int add3(int a, int b, int c)
{
    return a + b + c;
}

int main() {
    int v = 0;

    std::function<int(int,int)> fp =  
                    std::bind(add3, std::placeholders::_1, std::placeholders::_2, 30); 

    int (*ffp)(int,int) = *fp.target<int (*)(int,int)>(); 

    return 0;

}

I need to convert std::function object to C style function pointer.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 5
    you cannot do this. – Raildex May 31 '23 at 10:53
  • 2
    Unfortunately, C++ does not work this way. What's stored inside this `std::function` is not a plain function pointer but an anonymous callable object, what gets returned from `std::bind`, as such its type does not match `std::function::target`'s template parameter and it returns a `nullptr`. – Sam Varshavchik May 31 '23 at 10:55
  • You cannot, also avoid using std::bind and lookup lambda expressions (lambda functions). You sometimes CAN convert a lambda to a function pointer but only if it doesn't capture any variables. – Pepijn Kramer May 31 '23 at 10:58
  • You *only* can get back a function pointer if there's actually a function pointer stored within. That's comparable to `static_cast(&someFunctionAcceptingTwoIntsReturningInt)` vs. `static_cast(someCallableObject)`, the latter will fail for the same reason, an object is not a function pointer... – Aconcagua May 31 '23 at 10:59
  • It looks as if you intend to use a C++ object as a callback object to some C API – this requires some support by the C-API in question, though, typically by allowing to pass some custom `void*` pointer back to the callback. If that's not the case you are out of luck; if you absolutely require an object then you need to fallback to other mechanisms (like e.g. storing the pointer in a static or `thread_local` member variable that can be accessed by e.g. a static member function – that one *can* be assigned to a normal function pointer). – Aconcagua May 31 '23 at 11:07
  • 1
    In your concrete – though apparently much simplified – example you could work with a wrapper function: `int add30(int a, int b) { return add(a, b, 30); }` – depending on what 30 represents in your real scenario this might or might not be applicable... – Aconcagua May 31 '23 at 11:09
  • fwiw, `std::bind` does not (necessarily) return a `std::function`. If you actually need to get a function pointer to `add3` with captured `c` parameter then neither `std::function` nor `std::bind` are essential to your problem. – 463035818_is_not_an_ai May 31 '23 at 12:10

0 Answers0