检测特定虚函数的vtable索引/序号(使用Visual C++)

Jon*_*Jon 3 c++ visual-c++

继我的问题:检测特定虚函数的vtable偏移量(使用Visual C++):

鉴于:

struct A 
{
   virtual void a() {}
   virtual void b() {}
   virtual void c() {} 
};
Run Code Online (Sandbox Code Playgroud)

如何在Visual C++中编写函数(可能是非可移植的),这样:

int x = GetVtableIndex(&A::a); //returns 0
int x = GetVtableIndex(&A::b); //returns 1
int x = GetVtableIndex(&A::c); //returns 2
Run Code Online (Sandbox Code Playgroud)

我想要这样做的原因在于链接问题.

Iva*_*son 7

受到imre答案的启发,如果你只是想知道vtable的总大小; 即,有多少虚拟功能,这可能有效.此方法不实例化该类.

template <typename T>
int VTableSize()
{
    class VTableCounter
    {
    public:
        virtual int Get1() { return 0; }
        virtual int Get2() { return 1; }
        virtual int Get3() { return 2; }
        // ... 994 more ...
        virtual int Get998() { return 997; }
        virtual int Get999() { return 998; }
        virtual int Get1000() { return 999; }
    };

    class A : public T
    {
    public:
        virtual int LastVirtual() {return -1;}
    };

    VTableCounter vt;
    return reinterpret_cast<A*>(&vt)->LastVirtual();
}
Run Code Online (Sandbox Code Playgroud)

注意我没有使用Boost.PP,因为我可以告诉它限制为256.您应该能够使用vim宏或其他东西来获取任意数量的虚拟内容.但是,如果使用多个或虚拟继承,它可能会给出不正确的值.


Jon*_*Jon 7

受到imre和Ivan的回答的启发,我认为这可以完全解决:

template <class T, typename F>
int VTableIndex(F f)
{
    struct VTableCounter
    {
        virtual int Get1() { return 1; }
        virtual int Get2() { return 2; }
        virtual int Get3() { return 3; }
        virtual int Get4() { return 4; }
        // ... more ...
    } vt;

    T* t = reinterpret_cast<T*>(&vt);

    typedef int (T::*GetIndex)(); 
    GetIndex getIndex = (GetIndex)f;
    return (t->*getIndex)();
}

int n = VTableIndex<A>(&A::c); //returns 3
Run Code Online (Sandbox Code Playgroud)