helpmealot
asked on
Function ptr -> void * -> Function ptr
I have this code, which does not compile.
{ void (CTestaesr23Dlg::*pfnwSC)( void);
m_Map.SetAt ("func", (void *) &pfnwSC);
}
//void (CTestaesr23Dlg::*pfn) (void) = &CTestaesr23Dlg::func;
//(this->*pfn)();
{ void (CTestaesr23Dlg::*pfn) (void);
void *apfn;
m_Map.Lookup ("func", apfn);
pfn = (void (CTestaesr23Dlg::*)(void)) apfn;
(this->*pfn)();
}
Essentially, I want to make a map of strings to member function pointers. That is, given a string, I want a pointer to a class member function. I am using the MFC class CMapStringToPtr because I think this is what's necessary.
Unfortunately, I can't seem to figure out how to cast a void * pointer back to a void (CTestaesr23Dlg::*)(void) pointer. Is this how I approach the problem? What am I doing wrong?
Thanks for any help.
{ void (CTestaesr23Dlg::*pfnwSC)(
m_Map.SetAt ("func", (void *) &pfnwSC);
}
//void (CTestaesr23Dlg::*pfn) (void) = &CTestaesr23Dlg::func;
//(this->*pfn)();
{ void (CTestaesr23Dlg::*pfn) (void);
void *apfn;
m_Map.Lookup ("func", apfn);
pfn = (void (CTestaesr23Dlg::*)(void))
(this->*pfn)();
}
Essentially, I want to make a map of strings to member function pointers. That is, given a string, I want a pointer to a class member function. I am using the MFC class CMapStringToPtr because I think this is what's necessary.
Unfortunately, I can't seem to figure out how to cast a void * pointer back to a void (CTestaesr23Dlg::*)(void) pointer. Is this how I approach the problem? What am I doing wrong?
Thanks for any help.
You can't use
pfn = (void (CTestaesr23Dlg::*)(void)) apfn;
because it protected by compiler.
but you can cheat it with this:
memcpy((void*)&pfn, apfn, sizeof(apfn));
pfn = (void (CTestaesr23Dlg::*)(void))
because it protected by compiler.
but you can cheat it with this:
memcpy((void*)&pfn, apfn, sizeof(apfn));
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
One important point. When using the "myThis" technique, you need to remember that the object (CMyDlg) must be a singleton. If you instantiate another copy of the object, the static myThis will be wrong.
-- Dan
-- Dan
I had that problem before... I don't remember how well it worked, but I think I used a static member function and a static pointer to an instance of the class, which I would set before calling the function... I think. It was a while back.
class myClass
{
int myData;
//static member func and static pointer
static void staticFunc( void );
static MyClass *currentInstance;
}
static void myClass::staticFunc( void )
{
cout << currentInstance->myData << endl;
}
You can then use it like this...
Supposing you want to call the staticFunc() function of the instance inst...
myClass inst;
//set pointer to desired instance
MyClass::currentInstance = &inst;
//call the member function (or a pointer to it, or whatever)
MyClass::staticFunc();
class myClass
{
int myData;
//static member func and static pointer
static void staticFunc( void );
static MyClass *currentInstance;
}
static void myClass::staticFunc( void )
{
cout << currentInstance->myData << endl;
}
You can then use it like this...
Supposing you want to call the staticFunc() function of the instance inst...
myClass inst;
//set pointer to desired instance
MyClass::currentInstance = &inst;
//call the member function (or a pointer to it, or whatever)
MyClass::staticFunc();
It looks like DanRollins already said essentially the same thing I did... sorry.
BTW, DanRollins, I don't agree with this:
>The problem is that you can't call member fn, except static
> member fns, through a pointer.
You can call even a none-static member function against an
object through a pointer exactly as helpmealot does it:
(this->*pfn)();
>The problem is that you can't call member fn, except static
> member fns, through a pointer.
You can call even a none-static member function against an
object through a pointer exactly as helpmealot does it:
(this->*pfn)();
ASKER
I think I have found a solution that seems to be most straightforward.
Rather than use the CMapStringToPtr class, I've switched to the CMap class, which uses templates.
I now have the following code, which does compile and works perfectly:
-------
void CTestaesr23Dlg::OnButton1( )
{ CMap<CString, LPCSTR, void (CTestaesr23Dlg::*) (void), void (CTestaesr23Dlg::*) (void)> m_Map;
{ m_Map.SetAt ("func", func);
m_Map.SetAt ("func2", func2);
}
{ void (CTestaesr23Dlg::*pfn) (void);
m_Map.Lookup ("func", pfn);
(this->*pfn)();
void (CTestaesr23Dlg::*pfn2) (void);
m_Map.Lookup ("func2", pfn2);
(this->*pfn2)();
}
}
------------------
func and func2 are both executed.
Rather than use the CMapStringToPtr class, I've switched to the CMap class, which uses templates.
I now have the following code, which does compile and works perfectly:
-------
void CTestaesr23Dlg::OnButton1(
{ CMap<CString, LPCSTR, void (CTestaesr23Dlg::*) (void), void (CTestaesr23Dlg::*) (void)> m_Map;
{ m_Map.SetAt ("func", func);
m_Map.SetAt ("func2", func2);
}
{ void (CTestaesr23Dlg::*pfn) (void);
m_Map.Lookup ("func", pfn);
(this->*pfn)();
void (CTestaesr23Dlg::*pfn2) (void);
m_Map.Lookup ("func2", pfn2);
(this->*pfn2)();
}
}
------------------
func and func2 are both executed.
>> BTW, DanRollins, I don't agree with this:
>> >The problem is that you can't call member fn, except static
>> > member fns, through a pointer
You are right. This works:
typedef void (CMyDlg::*VFuncPtrToMember _v)(void);
void CMyDlg::OnButton1()
{
VFuncPtrToMember_v pfnNonStatic= DoSomething; // non-static
(this->*pfnNonStatic)();
}
Thanks Zoppo, I have learned something new today and am a better man because of it!
-==-=-=-=--==-=-=-
helpmealot,
It looks like you solved this one yourself. I have one tip, though. If you use a typedef, the code is quite a bit cleaner:
typedef void (CMyDlg::*VFnPtr_v)(void);
void CMyDlg::OnButton1()
{
CMap<CString, LPCSTR, VFnPtr_v, VFnPtr_v> m_Map;
m_Map.SetAt ("func", DoSomething);
m_Map.SetAt ("func2", StopIt);
VFnPtr_v pfn;
m_Map.Lookup ("func", pfn);
(this->*pfn)();
}
-- Dan
>> >The problem is that you can't call member fn, except static
>> > member fns, through a pointer
You are right. This works:
typedef void (CMyDlg::*VFuncPtrToMember
void CMyDlg::OnButton1()
{
VFuncPtrToMember_v pfnNonStatic= DoSomething; // non-static
(this->*pfnNonStatic)();
}
Thanks Zoppo, I have learned something new today and am a better man because of it!
-==-=-=-=--==-=-=-
helpmealot,
It looks like you solved this one yourself. I have one tip, though. If you use a typedef, the code is quite a bit cleaner:
typedef void (CMyDlg::*VFnPtr_v)(void);
void CMyDlg::OnButton1()
{
CMap<CString, LPCSTR, VFnPtr_v, VFnPtr_v> m_Map;
m_Map.SetAt ("func", DoSomething);
m_Map.SetAt ("func2", StopIt);
VFnPtr_v pfn;
m_Map.Lookup ("func", pfn);
(this->*pfn)();
}
-- Dan
ASKER
Ah good point, I hadn't thought of that. Thank you! :) If there are no objections, I suppose I'll delete this question in a day or two.
Actually, you should choose the comment that gave you the most advice and accept it as the answer to award the points to that expert.
ASKER
Yes, you are right, I appologize. It's only 50 points anyway. I therefore have decided to award points to DanRollins as his comments helped me the most overall.
Thank you for the input everyone!
Thank you for the input everyone!
>Thanks Zoppo, I have learned something new today and am a better man because of it!
You're welcome...
You're welcome...
If it's only a few, you may be able to use just a static struct with both the strings and the pointers to functions.