WEB开发网
开发学院软件开发VC 直接调用类成员函数地址 阅读

直接调用类成员函数地址

 2010-07-25 20:45:42 来源:WEB开发网   
核心提示:每次都定义一个函数类型并且进行一次强制转化,这个事是比较烦的,直接调用类成员函数地址(4),能不能将这些操作写成一个函数,然后每次调用是指定函数地址和参数就可以了呢?当然是可以的,强制转化,准备this指针,并且我已经写了一个这样的函数,//调用类成员函数//callflag:成员函数调用约定类型,0--thiscal

每次都定义一个函数类型并且进行一次强制转化,这个事是比较烦的,能不能将这些操作写成一个函数,然后每次调用是指定函数地址和参数就可以了呢?当然是可以的,并且我已经写了一个这样的函数。

//调用类成员函数
//callflag:成员函数调用约定类型,0--thiscall,非0--其它类型.
//funcaddr:成员函数地址.
//This:类对象的地址.
//count:成员函数参数个数.
//...:成员函数的参数列表.
DWORD CallMemberFunc(int callflag,DWORD funcaddr,void *This,int count,...)
{
  DWORD re;
  if(count>0)//有参数,将参数压入栈.
  {
    __asm
    {
      mov ecx,count;//参数个数,ecx,循环计数器.
      mov edx,ecx;
      shl edx,2;
      add edx,0x14; edx = count*4+0x14;
   next:  push dword ptr[ebp+edx];
      sub  edx,0x4;
      dec  ecx 
      jnz  next;
    }
  }
  //处理this指针.
  if(callflag==0) //__thiscall,vc默认的成员函数调用类型.
  {
    __asm mov ecx,This;
  }
  else//__stdcall
  {
    __asm push This;
  }
  __asm//调用函数
  {
    call funcaddr;
    mov re,eax;
  }
  return re;
}
使用这个函数,则上面的两个调用可以这样写:

CallMemberFunc(0,ptr1,&abc,3,5,'a',"7xyz");//第一个参数0,表示采用__thiscall调用.

CallMemberFunc(1,ptr2,&abc,3,5,'a',"7xyz");//第一个参数1,表示采用非__thiscall调用.

需要说明的是,CallMemberFunc是有很多限制的,它并不能对所有的情况都产生正确的调用序列。原因之一是它假定每个参数都使用了4个字节的栈空间。这在大多数情况下是正确的,比如参数为指针,char,short,int,long以及对应的无符号类型,这些参数确实都是每一个参数使用了4字节的栈空间。但是还有很多情况下,参数不使用4字栈空间,比如double,自定义的结构或类.float虽然是占了4字节,但编译器还产生了一些浮点指令,而这些无法在CallMemberFunc被模拟出来,因此对float参数也是不行的。

总结一下,如果成员函数的参数都是整型兼容类型,则可以使用CallMemberFunc调用函数地址。如果不是,那就只有按前面的方法,先定义对应的普通函数类型,强制转化,准备this指针,然后调用普通函数指针。

上一页  1 2 3 4 5 6  下一页

Tags:直接 调用 成员

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接