Important to note that unless you can change the signature of the code taking the function, there is no (easy) way to do this. That would be trying to implement a closure in a language that does not have closures that are the same as functions (the signature for a closure in C++ is different).
There are two actual ways to achieve this:
- Use some sort of singleton/global variable that you store the closure in, and then pass a helper function that calls the needed function using that closure. Here is an example:
#include <stdio.h> template<class C, typename ReturnType, typename... Args> class ClosureSingleton { typedef ReturnType (C::*FuncType)(Args...); public: static ClosureSingleton& getInstance() { static ClosureSingleton instance; return instance; } void setClosure(C* obj, FuncType f) { this->obj = obj; this->function = f; } static ReturnType funcPtr(Args... args) { C* obj = getInstance().obj; auto func = getInstance().function; return (obj->*func)(args...); } private: ClosureSingleton() {} C* obj; FuncType function; public: ClosureSingleton(ClosureSingleton const&) = delete; void operator=(ClosureSingleton const&) = delete; }; class aClass { public: void aTest1(int a, int b) { printf("%d + %d = %d\n", a, b, a + b); } int aTest2(int a, int b) { return a + b; } }; void function1(void (*function)(int, int)) { function(1, 1); } int function2(int (*function)(int, int)) { return function(1, 1); } int main() { aClass tmp; ClosureSingleton<aClass, void, int, int>::getInstance().setClosure( &tmp, &aClass::aTest1); function1(&ClosureSingleton<aClass, void, int, int>::funcPtr); ClosureSingleton<aClass, int, int, int>::getInstance().setClosure( &tmp, &aClass::aTest2); printf( "function2: %d\n", function2(&ClosureSingleton<aClass, int, int, int>::funcPtr)); return 0; }
Of course, this has the obvious downside that the closure needs to be set before every call, as well as some thread safety issues. Not ideal, but potentially workable in specific circumstances
- Use something like asmjit or dynamic compilation to dynamically compile and pass the function in to the C code. This will only work on machines that allow heap section to be marked as executable. It is also very much non-portable as you will be writing assembly code to accomplish this. However, if you get it working, you will indeed have a true closure, albeit a substantially higher cost to creating the closure compared to how most programming languages implement closures (they do not duplicate the function assembly, instead they use a context object)
- Patch the lib/dll that has the function handler to change it's signature to allow a context object. Again, a very brittle and non optimal solution.
My original answer, which does not really answer the question, but people found it useful:
Not sure why this incredibly simple solution has been passed up:
#include <stdio.h> class aClass { public: void aTest(int a, int b) { printf("%d + %d = %d\n", a, b, a + b); } }; template<class C> void function1(void (C::*function)(int, int), C& c) { (c.*function)(1, 1); } void function1(void (*function)(int, int)) { function(1, 1); } void test(int a,int b) { printf("%d - %d = %d\n", a , b , a - b); } int main (int argc, const char* argv[]) { aClass a; function1(&test); function1<aClass>(&aClass::aTest, a); return 0; }
Output:
1 - 1 = 0 1 + 1 = 2