简体   繁体   English

C ++:Visual Studio 2013中奇怪的虚拟成员函数指针

[英]C++: Strange virtual member function pointers in Visual Studio 2013

I am just puzzled by the following: 我对以下内容感到困惑:

struct InterfaceABC {
    virtual int printPolymorphic(int a) {
        return a;
    }
}

struct WithInterfaces : public InterfaceABC {
    virtual int printPolymorphic(int a) { return a; }
};

When I now do: 现在执行的操作:

address = &WithInterfaces::printPolymorphic;

I get this in the debugger: 我在调试器中得到这个:

0x012e52a9 {unittests.exe![thunk]:MockMe::WithInterfaces::`vcall'{4,{flat}}' }'}

BUT, the following invokation will not land there: 但是,以下发票将不会到达那里:

((InterfaceABC*) new WithInterfaces())->printPolymorphic(3);

After a day of effort I found out how to "reliably" (famous last words) get the real virtual address using C++ code, which gives me: 经过一天的努力,我发现了如何使用C ++代码“可靠地”(著名的最后一句话)获得真实的虚拟地址,这给了我:

0x012e6ece {unittests.exe!MockMe::WithInterfaces::printPolymorphic(int)}

So what do we have here? 那我们这里有什么?

WithInterfaces().printPolymorphic(3)

Will be calling 会打电话

0x012e6ece {unittests.exe!MockMe::WithInterfaces::printPolymorphic(int)}

And so will 所以也会

((InterfaceABC*)new WithInterfaces())->printPolymorphic(3);

... ...

Visual Studio implements the stub function justfor me :) huh? Visual Studio为我实现了存根函数:)嗯? I feel flattered... but 我感到受宠若惊...但是

address = &WithInterfaces::printPolymorphic;

this will not at all give you the function address. 这根本不会给您功能地址。 It will give you an address to a function that is never called and can never be called without hackery. 它为您提供了一个函数的地址,该函数永远不会被调用,并且没有黑客就永远不会被调用。

Anyone has some great ideas as to why this is? 任何人都对这为什么有一些好主意? And maybe also some ideas about how to REALLY get the real address without writing about 100 lines scary C++ madness that probably no one but me understands from all the people that will be reviewing the code? 也许还有一些关于如何真正地获得真实地址而又不写约100行的令人恐惧的C ++疯狂的想法,只有我一个人会从所有将审查代码的人那里了解到这吗? That is, in a standard compliant way... 也就是说,以符合标准的方式...

Taking the address of WithInterfaces::printPolymorphic gives you back a thunk that, when invoked, dispatches to the correct function to call based on the type of the object. 使用WithInterfaces::printPolymorphic的地址WithInterfaces::printPolymorphic使您返回一个thunk,在调用该thunk时,它会根据对象的类型调度到正确的函数以进行调用。

If you call a virtual member function on an object, the compiler emits code to look up a pointer to the correct implementation in the virtual function table ( vtable ) of the object and then invokes that function. 如果在对象上调用虚拟成员函数,则编译器将发出代码以在对象的虚拟函数表( vtable )中查找指向正确实现的指针,然后调用该函数。

A pointer to a virtual member function encapsulates this behavior, which you made explicit by looking at the generated thunk. 指向虚拟成员函数的指针封装了此行为,您可以通过查看生成的thunk使其明确。

It will give you an address to a function that is never called and can never be called without hackery. 它为您提供了一个函数的地址,该函数永远不会被调用,并且没有黑客就永远不会被调用。

The logic for it, however, is contained in every single call to a virtual function. 但是,它的逻辑包含在对虚拟函数的每次调用中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM