More portable way is using templates.
A good place to start is a reflection library
here.
The key idea is to have a set of "invoker" functions all with the same prototype - void Invoker(FUNC_PTR func, void** args, void* result). FUNC_PTR here is a special type that holds an actual function pointer, you cannot use a simple void* because function pointer can be bigger in case of complex class hierarchies.
Invoker is responsible to cast and unpack all parameters and make the legal Cpp call. And because all invokers have the same prototype they can be stored uniformly.
Here's the example of such invokers for function and class method with two parameters (not counting implicit 'this' in method case):
#define MAKE_FPTR() FT mptr = FunctionCast<FT>(fptr)#define UNPCK_ARG(T, ARG) (*(T*)args[ARG])#define UNPCK_RET() (*(RT*)res)#define UNPCK_INS(T, ARG) (*(T**)args[ARG])#define UNPCK_INS_CALL(T, ARG, MPTR) (UNPCK_INS(C, ARG)->*MPTR)template<class FT, class A1, class A2, class RT>void InvokeFunction(FUNC_PTR fptr, void** args, void* res){ UNPCK_RET() = FunctionCast<FT>(fptr)(UNPCK_ARG(A1, 0), UNPCK_ARG(A2, 1)); }template<class FT, class C, class A1, class A2, class RT>void InvokeMethod(FUNC_PTR fptr, void** args, void* res){ MAKE_FPTR(); UNPCK_RET() = UNPCK_INS_CALL(C, 0, mptr)(UNPCK_ARG(A1, 1), UNPCK_ARG(A2, 2));}
I've generated all my invokers with simple Python script :)
Invoker creation can be simplified by another set of functions which allow template argument deduction (also generated). You can also add a runtime argument validation.
This is not easy approach, but it allows to handle such complex cases like reference return types etc.