在运行时访问v表

Access v-table at run-time

本文关键字:访问 运行时      更新时间:2023-10-16

是否可以在运行时访问函数的v表?是否可以确定诸如不同功能版本的数量之类的元信息?这可能更像是一个理论问题,但是开发人员是否可以通过确保v-table永远不会超过一定的行数来限制可以扩展给定基类的类的数量?

是否可以在运行时访问函数的v表?是否可以确定诸如不同功能版本的数量之类的元信息?

不以可移植的方式。该标准甚至没有虚拟表的概念,它更多的是实现细节而不是需求,即使我知道的所有实现都使用虚表。在一般情况下,在运行时甚至没有足够的信息可用(即编译器不需要在虚表中存储条目的数量,因为它看到类型并可以计数)

开发人员是否可以通过确保v-table永远不会超过一定数量的行来限制可以扩展给定基类的类的数量?

还是没有,但由于这显示了一种误解,可能值得将其分开处理。当基类有任何虚函数时,编译器(在所有使用虚表的实现中)将创建虚函数表,并且该虚函数表在基类中每个虚函数只有一个条目(加上一些额外的数据——类型信息或指向它的指针,到对象开头的偏移量或其他实现细节)。当类扩展基类时,它不会向虚值表添加新元素,而是创建一个单独的虚值表(或更多,取决于类型层次结构)。如果派生函数没有添加任何新的虚函数,则派生对象的虚函数表将包含与原始虚函数表相同的元素数量。也就是说,您可以拥有巨大的继承层次结构,而不会影响虚函数表的布局。改变的是存储的typeinfo数据和指向每个虚函数的指针,它们将引用最终重写

一个元信息,如不同函数版本的数量被确定?

No c++不支持反射你想要实现的是不可能在c++ AFAIK

理论上,是的,因为它存储在内存中,您可以访问它。在实践中,没有统一的、可移植的方法来实现它,因为编译器可以自由地以它想要的任何方式实现虚函数,所以您必须仔细研究编译器的源代码,以找出如何/在哪里访问所需的信息以及如何解释它。

对于您的努力,我能想到的唯一一线希望就是dynamic_cast的处理。每个具有相应库支持的编译器都有一些遍历层次结构以实现动态强制转换的概念。如果可以钩入该遍历,那么就可以知道正在处理多少层继承。也就是说,即使您做到了这一点,它也是特定于编译器的(正如其他人所说),因为这样的实现是专有的。

您可以使用调试接口访问SDK或其他调试支持接口(gdb)进行此类操作。

RTT数据更易于移植,但可能没有足够的细节用于您的项目。

对于限制v-table并防止其过度扩展的具体问题,您可以尝试以下方法;

IDiaSymbol: get_classParente 检索对该符号的类父类的引用。

HRESULT get_classParent (IDiaSymbol** pRetVal);

你可以在这里调查所有与类相关的符号类型,你可能想要做的是枚举所有加载的类类型,get_clasparent递归地并保留所有扩展基类的类计数。

你的类也可以要求符号在启动时可用,以帮助执行