如何确定虚函数在虚函数表中的位置3 (Linux x64版本)
之前2篇Blog说明了如何在Windows下确定虚函数在虚函数表中的位置
这里说明Linux gcc是如何得到虚函数在表中的位置。
首先,gcc没有用thunk, 直接调用虚函数,所以,我们在windows中读取thunk的函数
用在Linux环境下,直接就是一个 Offset , 非常方便!
template <typename T>
union TFP;
// 特化模板,支持成员函数指针
template <typename ClassType, typename ReturnType, typename... Args>
union TFP<ReturnType(ClassType::*)(Args...)> {
using MemberFuncPtr = ReturnType(ClassType::*)(Args...); // 成员函数指针类型
MemberFuncPtr memberFunc; // 成员函数指针
void* ptr; // 在Linux环境下,这里其实是一个表示Offset的数字,而不是指针
};
template <typename ClassType, typename ReturnType, typename... Args>
uint64_t GetMemberFnOffset(ReturnType(ClassType::* func)(Args...))
{
TFP<decltype(func)> fp;
fp.memberFunc = func;
return (uint64_t)fp.ptr;
}
但是有一点需要注意,获得的Offset不要直接使用,而是确定虚函数的次序
例如下图:
我们看到第一个函数setCallback 的 Offset 为 17, 下一个函数init的Offset为 25, 就是 17 + 8
其实真正的第一个函数是类的析构函数,他的Offset为 9
至于为什么不是8,或者 0, 我也不知道…