0

I want to call a C API from C++. The API expects a function pointer, though for me the functionality is implemented in a C++ function object because it has state.

In fact the desired functionaliity is split across into two function objects. The C api expects a function that has two pointer parameters for returning the two things that each of the function objects return.

Apart from defining a global function is there any way of using the function object from C. For example can it be reinterpret_casted to a function pointer ?

EDITS:

For simplicity its ok to assume that the signature of the call back is void (*f)(void*, int*, int*)

Oh and it has to be C++-03

san
  • 4,144
  • 6
  • 32
  • 50

1 Answers1

3

Most APIs allow you to pass some kind of user state along through a void pointer. You can pass a pointer to your object through there:

struct my_obj
{
    void operator()(int*, int*) {}

    static void forwarder(void *state, int *x, int *y) { (*(my_obj*)state)(x, y); }
};

void install_fn(void (*)(void*,int*,int*), void *state);

my_obj obj;
install_fn(my_obj::forwarder, &obj);

For APIs which don't allow you to pass any state (GLUT is one of the only ones I've found that come to mind), you're out of (portable) luck.

Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
  • 1
    When the API doesn't directly support passing state information, it can still be done. One way is simply the good old global variable. Which needs to be tread local storage if threading involved. Another way is associating information with some data that is available, e.g. a Windows window property. A third is to use a machine code level trampoline function, generated on the fly. This was used by a Borland GUI framework, and it's the most efficient and safest thing, but perhaps a bit incompatible with today's "security" measures. – Cheers and hth. - Alf Dec 10 '12 at 04:59
  • I'd post an answer along those lines except the OP is too vague about the concrete case. :-( – Cheers and hth. - Alf Dec 10 '12 at 05:00
  • Not completely out of portable luck... I've seen where someone interfaced through such an api using a facade that had a fixed-size set of static trampoline functions, along with a static free list of pointers to these trampolines (not trampolines in the compiler/object-file sense). When registering a function through the api, it would register the next free trampoline & take it off of the free list. And when called back, it would add itself back to the free list. And so on. Until it ran out of trampolines, in which case it would blow up... but it never did. – phonetagger Dec 10 '12 at 05:00
  • Holy cow, my nemesis "Cheers and hth. - Alf" posted what I was typing while I was typing it. – phonetagger Dec 10 '12 at 05:01
  • ...well, not quite I guess, but similar. – phonetagger Dec 10 '12 at 05:08
  • Indeed, using globals is possible but not really a scalable solution. That's definitely an interesting way to do it phonetagger -- one I hadn't thought of. – Cory Nelson Dec 10 '12 at 05:28
  • A while back I made something that'd generate x86 code for a function which had an actual function pointer and state pointer embedded in it. It's actually quite easy, just very non-portable. – Cory Nelson Dec 10 '12 at 05:29