c++虚函数地址的获取

最近在做的一个项目的一个步骤找到虚函数的实际地址。这个过程中遇到的问题,让我感觉到了自己对于C++指针的理解还是不够透彻,记录一下。

概念

  • 指针由两个空间组成
    • 一是指针本身占有一定的空间,32位操作系统下是4byte 32bit,64位操作系统下是8byte 64bit。
    • 二是这个占有的空间中存放一个地址,这个地址代表另一个空间,这个空间所占的大小信息由指针的类型表示。
  • 指针赋值
    • 直接=修改指针空间中保存的地址,从而改变指针的指向
    • 解引用*之后再=,是修改指针指向的空间所存放的值。

具体

获得虚函数地址

根据操作系统的位数定义指针的大小:

#ifdef _xxx32 //代表是32位操作系统
typedef unsigned int POINTER_SIZE
#else
typedef unsigned long long POINTER_SIZE
#endif

我需要获得虚表。虚表被多态对象的虚指针所指向,虚指针在多态对象的最前面。

PolymorphicObject* ppO;
POINTER_SIZE* vtable = (POINTER_SIZE*)(*(POINTER_SIZE*)ppO);

每一次类型转换,实际上都会产生一个临时变量,上面复杂的式子可以拆分成:

POINTER_SIZE* temp1 = ppO;
POINTER_SIZE temp2 = *temp1;
POINTER_SIZE* temp3 = temp2;
POINTER_SIZE* vtable = temp3;

前面提到,指针指向空间的大小是由指针的类型所知道的,这里做的是

  • 先将对象指针转换成POINTER_SIZE*,让编译器知道我们该空间的大小为sizeof(POINTER_SIZE)(实际上ppO所指向的空间并不止这么大,但我们只要指针大小的信息)。
  • 再将该指针所存储的地址取出来得到temp2,得到了虚表所在空间的首地址。
  • 因为虚表本是一个(函数)指针数组,最后将地址再次解释成POINTER_SIZE*得到temp3,最终vtable变量存储了虚表的首地址。

赋值给指针

我们知道函数的声明typedef void (__stdcall * pFunc)(void),要找的函数指针在虚表的INDEX位置,从而vtable[INDEX]就是目标函数指针的地址。

可此时得到的是POINTER_SIZE类型,还需要赋值给函数指针从而进一步操作。看起来好像很复杂,实际上,根据指针赋值的第一条,直接:pFunc p = (pFunc)vtable[INDEX]就搞定了。

PS:写完了才发现这么简单,当时是怎么想的,可能是看到函数指针就有点陌生,指针都只是无符号数而已,都是一样的-_-…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值