如何在不创建实例的情况下获取继承结构的基本 class 偏移量

How to get the base class offset of an inherited struct without creating an instance

考虑这段代码:

struct A {
    int64 member;
    int32 member2;
    virtual void f();
};

struct B {
    int16 member3;

    virtual void b();
};

struct C : A, B {
    virtual void b() override;
};

我有兴趣在 C 中找到 B 的偏移量。以前使用其他没有虚拟继承的结构并且第一个成员的只有一个基数 class offsetof 似乎可以工作。我已经反编译了一些代码(在 IDA 中),基本 classes 在此处很好地突出显示(十六进制):

在一个函数中,这些精确的基数class偏移量用于通过将偏移量添加到void*来将void*转换为派生的classes(通过转换char*)。 ABC 结构类似于编译代码中的结构,其中包括具有虚函数的 classes 和多个基 classes。

我的问题是他们是怎么做到的,我该怎么做?我试过 i32 offset = (i64)((B*)((C*)NULL)); 之类的方法,但没有成功。

我尝试了以下方法,并且有效:

(char*)(B*)(C*)0x100 - (char*)(C*)0x100

它将C*转换为B*;这应该可以完成工作。剩下的就是支持了。我使用了任意数字 0x100;它似乎适用于除 0 以外的所有数字。

为什么它对 0 不起作用:它看到类型为 C* 的空指针;将其转换为 B* 类型的空指针,它仍应为空。特例。

当然,这使用了未定义的行为。在我的简短测试程序中,它似乎可以在 Visual Studio 中工作;不保证它在其他任何地方都能正常工作。