zoukankan      html  css  js  c++  java
  • C++ Tips: Adjustor thunk: what is it, why and how it works

    转载自:

    http://blogs.msdn.com/b/oldnewthing/archive/2004/02/06/68695.aspx

    If you find yourself debugging in disassembly, you'll sometimes find strange little functions called "adjustor thunks". Let's take another look at the object we laid out last time:

    class CSample : public IPersist, public IServiceProvider
    {
      public:
      // *** IUnknown ***
      STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
      STDMETHODIMP_(ULONG) AddRef();
      STDMETHODIMP_(ULONG) Release();  // *** IPersist ***
      STDMETHODIMP GetClassID(CLSID* pClassID);  // *** IQueryService ***
    STDMETHODIMP QueryService(REFGUID guidService,REFIID riid, void** ppv);
    private:
     LONG m_cRef;
     ...
    };
     
    p    lpVtbl    QueryInterface (1)
    q    lpVtbl    QueryInterface (2)   AddRef (1)
    m_cRef AddRef (2) Release (1)
    ... Release (2) GetClassID (1)
    QueryService (2)

    In the diagram, p is the pointer returned when the IPersist interface is needed, and q is the pointer for the IQueryService interface.

    Now, there is only one QueryInterface method, but there are two entries, one for each vtable. Remember that each function in a vtable receives the corresponding interface pointer as its "this" parameter. That's just fine for QueryInterface (1); its interface pointer is the same as the object's interface pointer. But that's bad news for QueryInterface (2), since its interface pointer is q, not p.

    This is where the adjustor thunks come in.

    The entry for QueryInterface (2) is a stub function that changes q to p, and then lets QueryInterface (1) do the rest of the work. This stub function is the adjustor thunk.

    [thunk]:CSample::QueryInterface`adjustor{4}':  sub     DWORD PTR [esp+4], 4 ; this -= sizeof(lpVtbl)
                                                                        jmp CSample::QueryInterface

    The adjustor thunk takes the "this" pointer and subtracts 4, converting q into p, then it jumps to the QueryInterface (1) function to do the real work.

    Whenever you have multiple inheritance and a virtual function is implemented on multiple base classes, you will get an adjustor thunk for the second and subsequent base class methods in order to convert the "this" pointer into a common format.

    简言之,就是调整this指针,使其与实际执行的函数( QueryInterface(1) )保持一致,满足当前所执行函数的要求。这是C++的实现方式细节,用来解决非虚多继承时Vtbl layout的问题。参考:http://blogs.msdn.com/b/zhanli/archive/2010/07/01/c-tips-adjustor-thunk-what-is-it-why-and-how-it-works.aspx

  • 相关阅读:
    Vue2.0 $set()的正确使用方式
    Vue中axios踩坑之路-POST传参
    vue里使用create、mounted调用方法的正确姿势
    cmd返回上一级和根目录
    【积累】排序题积累
    【图论】2019 ICPC Malaysia National G(拓扑排序)
    2019 ICPC Malaysia National F(状态压缩)
    【线段树】扫描线学习笔记
    组合数(阶乘数质因子分解)
    【线段树】2019CCPC网络选拔赛 array(权值线段树)
  • 原文地址:https://www.cnblogs.com/smwikipedia/p/1798759.html
Copyright © 2011-2022 走看看