【发布时间】:2011-03-29 17:38:23
【问题描述】:
我从here 读到了有关调整器的信息。这里引用一段话:
现在,只有一个 QueryInterface 方法,但有两个条目,一个 对于每个 vtable。请记住,每个 vtable 中的函数接收 对应的接口指针作为它的 “这个”参数。这很好 查询接口(1);它的界面 指针与对象的相同 接口指针。但这是个坏消息 对于 QueryInterface (2),因为它 接口指针是q,不是p。
这就是调节器重击的地方 在。
我想知道为什么“vtable 中的每个函数都接收相应的接口指针作为其“this”参数”?它是接口方法用来在对象实例中定位数据成员的唯一线索(基地址)吗?
更新
这是我的最新理解:
其实我的问题不是这个参数的用途,而是为什么我们要使用对应的接口指针作为这个参数。抱歉我的含糊不清。
除了将界面指针用作对象布局中的定位器/立足点。当然还有其他方法可以做到这一点,只要你是组件的实现者。
但对于我们组件的客户端来说,情况并非如此。
当组件以 COM 方式构建时,我们组件的客户端对我们组件的内部一无所知。 客户端只能持有接口指针,而这正是将作为this参数传递给接口方法的指针。在这个期望下,编译器别无选择,只能根据这个特定的this指针生成接口方法的代码 .
所以上述推理得出的结果是:
必须确保每个功能 在 vtable 中必须收到 对应的接口指针作为它的 “这个”参数。
在“this pointeradjustor thunk”的情况下,单个 QueryInterface() 方法存在 2 个不同的条目,换句话说,可以使用 2 个不同的接口指针来调用 QueryInterface() 方法,但编译器只生成1 个 QueryInterface() 方法的副本。因此,如果编译器选择其中一个接口作为 this 指针,我们需要将另一个接口调整为所选择的接口。这就是这个调节器重击的目的。
BTW-1,如果编译器可以生成 2 个不同的 QueryInterface() 方法实例怎么办?每一个都基于相应的接口指针。这不需要调整器 thunk,但需要更多空间来存储额外但类似的代码。
BTW-2:从实施者的角度来看,有时一个问题似乎缺乏合理的解释,但从用户的角度可以更好地理解。
【问题讨论】: