Thunk技术就是申请一段可执行的内存,并通过手动构造CPU指令的形式来生成代码块,实现针对一些特定问题的解决方案,如:
- 通知我们要在窗口的回调函数里获得包含此窗口的类的指针得把窗口类指针放到窗口绑定的数据里,可是有一种技术可以帮助你省去这种绑定的麻烦。(如常见的问题:类的成员函数不能作为回调函数,也不能通过参数传递this的情况)。如下图:

因为是 WindowProc 是 __stdcall 调用约定,就算我们多压入了一个this参数,也不管调用者的事, 因为堆栈是由被调用者(windowProc)来清理的。虽然只有4个显式参数, 但作为成员函数的WindowProc在结束的时候是用ret 14h返回的,this被自动清除,你知道为什么吗?
我们只需构造如下的3条简单的指令即可:

- 我们知道一个窗口对映一个对象,很自然设计一个类。如MyWin *p1和MyWin *p2,在类里有窗口的句柄,这样就进入到window的程序世界里了。通过类可以找到窗口句柄,但通过窗口句柄怎么找到类,这就是一个比较难办的问题。
- 虚函数多继承情况。如class B : public A1, public A2, public A3{}。所谓的thunk就是一段汇编代码,这段汇编代码可以以适当的偏移值来调整this指针以跳到对应的虚函数中去,并调用这个函数,也就是说当使用A1的指针指向B的对象,不需要发生偏移,而使用A2的指针指向B则需要进行偏移sizeof(A1)个字节。并跳转到A1中的函数来执行。这就是通过thunk的jmp指令跳转到这个函数。
所以具体的虚函数表中的情况如下:
①如果两个基类中的虚函数名字不同,派生类只重写了第二个基类的虚函数,则不会产生thunk用以跳转。
②如果基类中虚函数名字相同,派生类如果重写,将会一次性重写两个基类的虚函数,这时候第二个基类的虚函数表中存放的就是thunk对象,当指针指向此处的时候,会自动跳转到A类的对应虚函数(已经被B重写)执行。如下图:重写虚函数f()

③第一个基类的虚函数被重写与否都不会产生thunk对象,因为这个类是被别的基类指针跳转的目标,而这个类的指针施行多态的时候是不会发生跳转的。
④派生类的重新定义的虚函数将会排在第一个虚函数表内部A1虚函数的后面,但是当A2调用这个函数的时候,会通过t
551



被折叠的 条评论
为什么被折叠?



