继我的问题:检测特定虚函数的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)
我想要这样做的原因在于链接问题.
受到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宏或其他东西来获取任意数量的虚拟内容.但是,如果使用多个或虚拟继承,它可能会给出不正确的值.
受到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)