Hook Direct3D EndScene代码中三个指针星号的含义咨询
解释Direct3D9代码中的
void***指针用法 这段代码的核心是提取Direct3D9设备的虚函数表(vtable),为后续Hook EndScene这类API做准备。要搞懂三重指针的作用,得先明确COM对象的内存布局:所有像IDirect3DDevice9这样的COM接口实例,内存结构的第一个成员永远是指向虚函数表的指针,而虚函数表本身是一个存储接口所有方法地址的函数指针数组。
现在拆解关键代码memcpy(pTable, *(void***)(pDummyDevice), size);里三个*的含义:
- 第一层
*:pDummyDevice本身就是IDirect3DDevice9*类型,也就是指向COM对象实例的指针,这是第一个指针层级。 - 第二层
*:COM对象实例的第一个成员是指向虚函数表的指针,把pDummyDevice强制转为void***时,第二层*代表“这个对象实例里存的是一个指向虚函数表的指针”。 - 第三层
*:我们最终需要的是虚函数表数组本身的起始地址,这样才能用memcpy复制整个表的内容。解引用void***类型的pDummyDevice,就能直接拿到这个数组的起始地址(void**类型),这就是第三个*的作用。
换个更直白的逻辑链:
pDummyDevice→ 指向COM对象实例的指针(void***)(pDummyDevice)→ 告诉编译器:这个指针指向的内容,是一个指向虚函数表数组的指针*(void***)(pDummyDevice)→ 解引用后得到虚函数表数组的起始地址,供memcpy复制整个表到pTable(也就是d3d9Device数组)
为什么不能只用一个*?如果只写*(void*)(pDummyDevice),得到的是对象实例第一个成员的数值(也就是虚函数表指针本身的值),而不是虚函数表数组的地址,根本没法用来复制整个表的内容。
内容的提问来源于stack exchange,提问作者Nitay Prozanski
相关产品推荐
相关产品推荐

