请教一个关于类成员回调的问题。
关于类成员回调的问题。我的想通过代码实现如下功能 B.Start() -> A.CallBack() -> B.fncallback()
代码如下:
class A
{
public:
inline void CallCallBack(void(*lpfn)(LPCTSTR),LPCTSTR lpstr)
{
(*lpfn)(lpstr);
}
};
class B
{
public :
inline void fncallback(LPCTSTR lpstr)
{
::MessageBox(NULL,lpstr,NULL,MB_OK);
}
inline void Start()
{
union
{
void(*lpfn1)(LPCTSTR);
void(B::*lpfn2)(LPCTSTR);
} _proc;
_proc.lpfn2 = &B::fncallback ;
A a;
a.CallCallBack(_proc.lpfn1,_T("callback string!"));
}
};
int main()
{
B b;
b.Start();
system("pause");
return 0 ;
}
调用过程成功了,MessageBox弹出来了,但是运行到下一步就提示错误
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
不知问题在哪里。如要实现这个功能有没好的办法?
望指教!
[解决办法]
可以将void (A::*CALLBACK)(LPCTSTR lpstr)使用union技巧转化成void (*func)(A*,LPCTSTR lpstr)。
不过我认为还是楼上说的那样用static。
[解决办法]
要使用类的成员函数指针,并且把B类的指针同时传给A.CallBack,大概是这样:
inline void CallCallBack(B* pB, void(Base::*lpfn)(LPCTSTR),LPCTSTR lpstr)
{
pB->lpfn(lpstr);
}
调用:
a.CallCallBack(this, _proc.lpfn1,_T("callback string!"));
[解决办法]
class B;
class A
{
public:
void CallCallBack(void(B::*lpfn)(LPCTSTR),LPCTSTR lpstr,B*ptr);
};
class B
{
public :
inline void fncallback(LPCTSTR lpstr)
{
::MessageBox(NULL,lpstr,NULL,MB_OK);
}
inline void Start()
{
union
{
void(*lpfn1)(LPCTSTR);
void(B::*lpfn2)(LPCTSTR);
} _proc;
_proc.lpfn2 = &B::fncallback ;
A a;
a.CallCallBack(_proc.lpfn2,_T("callback string!"),this);
}
};
void A::CallCallBack(void(B::*lpfn)(LPCTSTR),LPCTSTR lpstr,B*ptr)
{
(ptr->*lpfn)(lpstr);
}
int main()
{
B b;
b.Start();
return 0;
}
[解决办法]
class A
{
public:
inline void CallCallBack(void(__stdcall *lpfn)(LPCTSTR),LPCTSTR lpstr)
{
(*lpfn)(lpstr);
}
};
class B
{
public :
inline void fncallback(LPCTSTR lpstr)
{
::MessageBox(NULL,lpstr,NULL,MB_OK);
}
inline void Start()
{
union
{
void(__stdcall *lpfn1)(LPCTSTR);
void(B::*lpfn2)(LPCTSTR);
} _proc;
_proc.lpfn2 = &B::fncallback ;
A a;
a.CallCallBack(_proc.lpfn1,_T("callback string!"));
}
};
绝对没有任何问题
------解决方案--------------------
vc默认的是__thiscall,你改成__stdcall就好了