1

特定の仮想関数のvtableオフセットを検査できますか?

なんで?意図しないバイナリ互換性の破損を検出できるようにしたいと思います(バイナリ互換性の意味については、 http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2Bを参照してください)。

「/d1reportSingleClassLayout」(http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-)の文書化されていないサポートされていない手法を知っています。 c-and-fixing-lnk2022.aspx)であり、この手法を使用する予定ですが、可能であれば、いくつかの単純なコンパイル時または実行時のチェックも使用したいと思います。

4

3 に答える 3

5

ジェリーの答えに触発されて、私はなんとかこの関数を書き上げることができました。これは、どの関数のシグネチャに対しても同じことを行うことができます。

#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;
}
于 2011-04-08T04:37:44.180 に答える
2

それは醜い、携帯できない、無愛想ななどですが、おそらくこの一般的な順序の何かが役立つでしょう:

#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;
}

もう少し移植性を高めるには、おそらくunsigned charの配列をユニオンの2番目の要素として使用する必要があります。意味のある方法でそれを出力すると、もう少し作業が追加されます(少なくとも今のところは) )。

于 2011-04-08T03:43:21.283 に答える
1

ここに良い例があります。ただし、関数名は取得できず、アドレス/オフセットのみを取得できることに注意してください。

于 2011-04-08T03:40:45.423 に答える