Detect the the vtable offset of a specific virtual

2019-04-16 16:06发布

Can the vtable offset of a specific virtual function be inspected?

Why? I'd like to be able to detect unintentional binary compatibility breaks (see http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B for what I mean by binary compatibility).

I'm aware of the undocumented and unsupported technique of "/d1reportSingleClassLayout" (http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx), and I plan to use this technique, but I'd like to also use some simple compile time or run time checks if possible.

3条回答
叛逆
2楼-- · 2019-04-16 16:15

There's a good example here. Mind though that you won't be able to retrieve function name, just the address/offset.

查看更多
萌系小妹纸
3楼-- · 2019-04-16 16:27

It's ugly, non-portable, crufty, etc., but maybe something on this general order would be useful:

#include <iostream>

struct A { 
    virtual void a() {}
    virtual void b() {}
    virtual void c() {}
};

int main() { 
    A a;

    typedef void (A::*ptr)();

    union see_bits { 
        ptr p;
        int i;
    };

    see_bits x, y, z;
    x.p = &A::a;
    y.p = &A::b;
    z.p = &A::c;

    std::cout << x.i << "\n";
    std::cout << y.i << "\n";
    std::cout << z.i << "\n";

    return 0;
}

To be a bit more portable, you should probably use an array of unsigned char as the second element of the union -- printing that out in a meaningful manner will add a bit more work that I'll leave to you (at least for now).

查看更多
贼婆χ
4楼-- · 2019-04-16 16:31

Inspired by Jerry's answer, I managed to write up this function that can do the same thing for any function signature:

#include <iostream>

struct A
{
    virtual void a() {}
    virtual void b() {}
    virtual void c() {}
};

template <class T>
int SeeBits(T func)
{
    union
    {
        T ptr;
        int i;
    };
    ptr = func;

    return i;
}

int main()
{
    int i = SeeBits(&A::a);
    int j = SeeBits(&A::b);
    int k = SeeBits(&A::c);

    std::cout << i << " " << j << " " << k << std::endl;

    return 0;
}
查看更多
登录 后发表回答