dice wrote:
> Hi,
> In order to use an external api call that requires a function pointer I
> am currently creating static wrappers to call my objects functions.
> I want to re-jig this so I only need 1 static wrapper function.
The problem is that you need to pass the 'this' pointer to the function.
> I would prefer to be able to pass the member function as a void* to the
> static wrapper but I suspect this may not even be possible.
As a matter of fact, taking the address of a method is possible, but
wouldn't solve your problem, since you need to pass the 'this' pointer
as well (so you actually have to pass _two_ parameters to the function).
> Another solution would be option 2 below but I can't figure out the
> syntax to call obj->*pFn().
Of course. You don't have the 'this' pointer.
> typedef void (*ExecFn)(void *);
>
> void external_api_fn(ExecFn fn,void* p)
> {
> fn(p);
> }
>
> class Doit
> {
> public:
> void fn1(void){printf("fn1\n");}
> void fn2(void){printf("fn2\n");}
> //current solution
> static void static_wrapper1(void *obj)
> {
> ((Doit*)obj)->fn1();
> }
> static void static_wrapper2(void *obj)
> {
> ((Doit*)obj)->fn2();
> }
> //option 1
> static void static_wrapper3(void *fn)
> {
> //fn();
> }
> //option 2
> void (Doit::*pFn)(void);
> static void static_wrapper4(void *obj)
> {
> //execute pFn - obj->*pFn - how to execute pFn for obj?
> }
> //--
> Doit()
> {
> //what Im doing
> external_api_fn(static_wrapper1,this);
> external_api_fn(static_wrapper2,this);
> //option 1 - cast fn1 to void?
> //external_api_fn(static_wrapper3,fn1);
> //external_api_fn(static_wrapper3,fn2);
> //option 2
> pFn = fn1;
> external_api_fn(static_wrapper4,this);
> pFn = fn2;
> external_api_fn(static_wrapper4,this);
> }
> };
>
How about this:
#include <stdio.h>
typedef void (*ExecFn)(void);
void external_api_fn (ExecFn fn)
{
fn ();
}
class Doit
{
typedef void (Doit::*PtrToMemberForWrapperType) (void);
private:
static Doit* ms_ThisForWrapper;
static PtrToMemberForWrapperType ms_PtrMemberFuncForWrapper;
static void static_wrapper ()
{
// Invoke the member function of the static object.
(ms_ThisForWrapper->*ms_PtrMemberFuncForWrapper) ();
}
public:
void fn1(void) {printf("fn1\n");}
void fn2(void) {printf("fn2\n");}
void call_external_api_fn (PtrToMemberForWrapperType pMemberFunc)
{
// Store away the this pointer.
ms_ThisForWrapper = this;
ms_PtrMemberFuncForWrapper = pMemberFunc;
external_api_fn (&static_wrapper);
}
};
Doit:

trToMemberForWrapperType Doit::ms_PtrMemberFuncForWrapper = 0;
Doit* Doit::ms_ThisForWrapper = 0;
int main ()
{
Doit MyDoit;
MyDoit.call_external_api_fn (Doit::fn1);
return 0;
}
I took the liberty to change the definition of ExecFn to a function that
takes no arguments, since your members fn1 and fn2 don't take arguments.
The above solution is not intended for use in multi-threaded
applications, since it uses static class members. If you want to use
this in a multi-threaded app, you have to introduce a map that stores
these pointers for each thread that uses the class.
Regards,
Stuart