dice wrote:
Quote:
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.
Quote:
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).
Quote:
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.
Quote:
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::PtrToMemberForWrapperType 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