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

直接调用类成员函数地址

 2010-07-25 20:45:42 来源:WEB开发网   
核心提示:二、取成员函数的地址当然,引用某位大师的话:"在windows中,直接调用类成员函数地址(2),我们总是有办法的",同样,就是可以直接取私有成员函数的地址(大概在asm括号中,编译器不再检查代码的可访问性),不过缺点是它在vc6下是无法通过编译的,在C++中,我们也总是有办法的

二、取成员函数的地址

当然,引用某位大师的话:"在windows中,我们总是有办法的"。同样,在C++中,我们也总是有办法的。这个问题,解决办法已经存在了多年,并且广为使用(在MFC中就使用了)。一般有两个方法,一是使用内嵌的汇编语言直接取函数地址,二是使用union类型来逃避C++的类型转换检测。两种方法都是利用了某种机制逃避C++的类型转换检测,为什么C++编译器干脆不直接放开这个限制,一切让程序员自己作主呢?当然是有原因的,因为类成员函数和普通函数还是有区别的,允许转换后,很容易出错,这个在后面会有详细的说明。现在先看看取类成员函数地址的两种方法:

第一种方法:

template
void GetMemberFuncAddr_VC6(ToType& addr,FromType f)
{
  union
  {
  FromType _f;
  ToType  _t;
  }ut;
  ut._f = f;
  addr = ut._t;
}

这样使用:

DWORD dwAddrPtr;

GetMemberFuncAddr_VC6(dwAddrPtr,&tt::foo);

为什么使用模版? 呵呵,如果不使用模版,第二个参数该怎么些,写成函数指针且不说太繁琐,关键是没有通用性,每个成员函数都要单独写一个转换函数。

第二种方法:

#define GetMemberFuncAddr_VC8(FuncAddr,FuncType)
{
  __asm
  {
    mov eax,offset FuncType
  };
  __asm
  {
    mov FuncAddr, eax          
  };
}
这样使用:

DWORD dwAddrPtr;

GetMemberFuncAddr_VC8(dwAddrPtr,&tt::foo);

本来是想写成一个模版函数的,可惜虽然通过了编译,却不能正确运行。估计在汇编代码中使用模版参数不太管用,用offset取偏移量直接就得0。

上面的宏是可以正确运行的,并且还有一个额外的好处,就是可以直接取私有成员函数的地址(大概在asm括号中,编译器不再检查代码的可访问性)。不过缺点是它在vc6下是无法通过编译的,只能在VC8下使用。

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

Tags:直接 调用 成员

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