sorry , 以上是对函数指针的赋值方法,
你可以定义该函数的指针,然后用该指针。
class class1{
void funca();
void funcb();
}typedef void (class::*pvfn)();ss::funca()
{
pvfn ptemp =&class1::funcb;
}ssl::funcb()
{
...
}
你可以定义该函数的指针,然后用该指针。
class class1{
void funca();
void funcb();
}typedef void (class::*pvfn)();ss::funca()
{
pvfn ptemp =&class1::funcb;
}ssl::funcb()
{
...
}
提示:
Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast
可是我的目的是得到(void *)或者是(unsigned int)的值,而不是该函数的指针呀
unsigned int a;
sprintf(temp, "%p", funca);
sscanf(temp, "%d", &a);
{
...
Listen();
LRESULT CALLBACK Winproc(HWND hDlg,UINT wMsg,WPARAM wParam,LPARAM lParam);
...
}mysocket::mysocket()
{
HINSTANCE hInst;
WNDCLASS wndc; wndc.lpfnWndProc=(void *)&mysocket::Winproc;
wndc.cbClsExtra=0;
wndc.cbWndExtra=0;
wndc.hInstance=hInst;
...
RegisterClass(&wndc);
hWnd=CreateWindow(szAppName,"My Socket Server",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInst,NULL);// 为响应事件创建窗口
ShowWindow(hWnd,SW_HIDE);
UpdateWindow(hWnd);
}mysocket::Listen()
{
...
if(WSAAsyncSelect(ListenSocket,hWnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE)==SOCKET_ERROR)
{
closesocket(ListenSocket);
} listen(ListenSocket,5);
...
}mysocket::Winproc()
{
switch(wMsg)
{
case WM_SOCKET:
if(WSAGETSELECTERROR(lParam))
{
closesocket(wParam);
break;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
Accept=accept(&hConnect,wParam);
WSAAsyncSelect(Accept,hDlg,WM_SOCKET,FD_READ|FD_WRITE|FD_CLOSE);
Fire_ConnectionRequest(hConnect);// 激发ConnectionRequest事件
break;
case FD_READ:
Fire_DataArrival(outlen);
break;
case FD_WRITE:
Fire_Write();
break;
case FD_CLOSE:
Fire_Close();
break;
}
break;
}
return TRUE;
}
如果你一定要这转化为unsigned int, 用reinterpret_cast再转一次.不过这里你不应该用这个, 窗口过程应该是全局的或者是静态的
以下代码测试通过:VC6.0 WIN2000
class CTest{
public:
void funca();
void funcb();
};void CTest::funca()
{
typedef void (CTest::*PFUNCB)();
PFUNCB pFuncb = &CTest::funcb; //pFuncb就是需要的指针
unsigned long ul;
__asm mov eax,dword ptr [ebp-8]
__asm mov ul,eax
unsigned long *pbase = (unsigned long *)ul;
char *p = (char *)pbase ;
//char *p = (char *)ul;
unsigned short tmp;
memcpy(&tmp,p +1,2); //以下pfuncb 就是指向void CTest::funcb()的地址,5为一条JMP的字节数
unsigned long pfuncb = (unsigned long)pbase + tmp + 5;}void CTest::funcb()
{
}void CTestRTFDlg::OnButton1()
{
CTest a;
a.funca();
}
1。__asm mov eax,dword ptr [ebp-8]这条语句中为什么要ebp-8呢?
是因为pFuncb定义的是第一个变量,也就是说pFuncb最好定义为第一个变量,
如果想自己再填加变量,可以放在PFUNCB pFuncb = &CTest::funcb;这条语句后面的随便什么地方。2。pbase的实际意义是:
在pbase的这个地址上,实际上放着一条JMP语句,在我的机器上是以下
的一条代码(pbase =00401019 ),你的该条代码可能不同:
00401019 E9 F2 0C 00 00 jmp CTest::funcb (00401d10)
其中00401d10就是需要得到的地址。
class mysocket
{
...
Listen();
static LRESULT CALLBACK Winproc(HWND hDlg,UINT wMsg,WPARAM wParam,LPARAM lParam);
...
}然后直接强制转换就没有问题。
我试过改成静态函数就行,可是静态函数就不能引用类的数据成员,这一点好
像不好解决。jyu1221(天同) :
真是个汇编高手,佩服佩服!!!
不过,C++问题如果弄得只有汇编才可以处理,那C++也太没面子了 :)
具体到这个函数,我觉得,你做的控件应当是一个不显示的窗口,对于窗口,应该能够有一个地方保存一些用户数据,并提供方法查询。这样,你可以在创建时把this指针作为用户数据,然后通过窗口句柄查询。总之,应当有一个把HWnd和this联系起来的方法。