我一直想找一种通过指针直接访问vtable的方法,并发现了这篇文章:http://www.codeproject.com/Tips/90875/Displaying-vtable-when-debugging
它工作正常,我可以通过vtable条目调用函数。 但是我无法理解这一系列的deo:
void (**vt)() = *(void (***)())ptr;
ptr
是指向对象的指针。我怎样才能解读这一行以及vt
如何获得vtable地址?
谢谢。
答案 0 :(得分:2)
对象中_vtable的实际位置取决于编译器。代码假定_vtable地址首先存储在对象中(所有现代编译器似乎都这样做)。此外,每个类只有一个vtable,它存储在一个位置。因此,每个实例都有一个指向函数指针数组的地址。
基本上,您创建一个名为vt的变量,这是一个指向函数的指针数组,这些函数返回void并且不带参数。然后使用在对象的第一个成员(vtable的地址)中找到的内容初始化此变量。
(void (***)())ptr
表示将前4个(32位机器)或8个(64位机器)转换为指向返回void并且不带参数的函数指针数组的指针。
*(void (***)())ptr
返回那些4或8字节的内容,即vtable的地址。
答案 1 :(得分:1)
void (**vt)()
vt是指向某个函数的指针。此函数返回void并且不带参数
void (***)()
指向指向这种函数的指针的指针(即,一个指针级别多于上面的指针级别)。
首先,你将ptr转换为这样一个三级指针功能
然后,你得到它指向的东西(使用单*
),这是一个两级指针到函数,即。同一类型变量vt。这意味着你可以将它分配给vt,这就是这条线的作用。
为什么?
指向void-no-param函数的单个函数指针可以存储在这样的变量x:void(*x)()
中。并不完全相关,如果你想将一些数组传递给一个函数,你传递一个指针。 IE浏览器。这足以将数组地址存储在一个指针中以访问整个数组(如果长度已知)
这意味着void(**vt)()
可以存储(函数指针数组)的地址
vtable不是别的,只是一个函数指针数组。
如果你有一个Car类,它有一些变量,比如颜色和vtable,它使用eg。每个对象200字节。指向汽车的指针就像是指向200字节数组的指针,如果在代码中访问颜色,编译器会查找该颜色,例如。字节133并生成对它的访问。
vtable在此对象中的位置是实现定义的,但通常在开头。如果你有一个指向汽车的指针,它是一个指向200字节数组的指针,首先分成一些fucntion指针,然后分成一些其他数据......
=> vtable,即。一系列函数指针,从汽车的起始地址开始 =>如果你将汽车指针投射到指向vtable的指针,即。指向“函数指针数组”的指针,即。指向“指向函数的指针”的指针,并且你有vtable数组。