2014-12-06 90 views
0

我一直在寻找一种方式来直接通过指针访问虚函数表和整个此帖一:http://www.codeproject.com/Tips/90875/Displaying-vtable-when-debuggingC++:帮助理解这行代码

它工作正常,我可以通过虚函数表条目调用功能。 但我无法理解这行DEO的:

void (**vt)() = *(void (***)())ptr; 

ptr是指向一个对象。我怎样才能破译这一行,vt如何获得vtable地址?

谢谢。

+0

相关:[尝试此网站](http://cdecl.org)来解释类型。 – WhozCraig 2014-12-06 11:58:44

回答

1

void (**vt)()
vt是指向某个函数的指针。这个函数返回void并且不带任何参数。
void (***)()
指一个指针,指向指针指向这样的功能(即,一个指针水平比上述大)。

首先,you're铸造PTR这样的三电平指针到功能。
然后,你得到它指向(跟单*)的东西,这是一个二级指针到函数,即。相同类型的变量vt。这意味着你可以将它分配给vt,并且这个线的功能非常强大。

为什么?

单个函数指针空隙无PARAM功能可以被存储在这样的变量x:void(*x)()。并不完全相关,如果你想传递一些数组到一个函数,你传递一个指针。 IE浏览器。它足以将数组地址存储在指针中以访问整个数组(如果长度已知)。
这意味着void(**vt)()可以存储(地址)一个函数指针数组。
vtable不是别的,只是一个函数指针数组。

如果你有喜欢的颜色和虚函数表的某些变量的一类汽车,它使用如。每个对象200字节。指向汽车的指针就像指向200字节数组的指针,如果您访问代码中的颜色,编译器会查找该颜色处于例如。字节133并生成对其的访问。

其中vtable在此对象内部是实现定义的,但通常在开头。如果你有一个指向汽车的指针,它是一个指向200字节的指针,首先被分成一些指针指针,然后是其他一些数据...

=> vtable,一组函数指针,从汽车的起始地址开始。
=>如果您将汽车指针投射到指向vtable的指针,即。指向“函数指针数组”的指针,即。指向“指向函数的指针的指针”,并且尊重你有vtable数组。

2

_vtable在对象中的实际位置依赖于编译器。该代码假定_vtable地址首先存储在对象中(所有现代编译器似乎都这样做)。另外,每个类只有一个vtable,它存储在一个单独的位置。因此,每个实例都有一个指向函数指针数组的地址。

基本上,创建变量VT命名,即指针到返回void并且不采取任何参数的函数的阵列。然后,使用在对象的第一个成员(vtable的地址)中找到的内容初始化此变量。

(void (***)())ptr 

意味着你施放此第一4(32位机)或8(64位机)的指针的函数指针返回void和不带参数的阵列。

*(void (***)())ptr 

返回那些4或8字节的内容,即vtable的地址。