问题标签 [vtable]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
12043 浏览

c++ - 用于多重虚拟继承和类型转换的虚拟表和虚拟指针

我对 vptr 和内存中对象的表示有点困惑,希望你能帮助我更好地理解这件事。

  1. 考虑B继承自A并且都定义虚函数f()。从我了解到的 B 类对象在内存中的表示形式如下所示:并且[ vptr | A | B ] 指向contains 。我也明白,将对象从to投射到除了忽略对象末尾的部分之外,什么也不做。这是真的吗?这种行为是不对的吗?我们希望该类型的对象执行method 而不是.vtblvptrB::f()BABAA::f()B::f()

  2. 系统中是否有一些vtables作为类的数量?

  3. vtable从两个或多个类继承的类的外观如何?C 的对象将如何在内存中表示?

  4. 与问题 3 相同,但具有虚拟继承。

0 投票
3 回答
834 浏览

com - 在 x86 程序集中构建 COM 对象 vtable

我正在使用 NASM 在 x86 程序集中构建一个 COM 对象。我非常了解 COM,我也非常了解 x86 程序集,但是让两者相互融合让我挂断了……(顺便说一句,如果你想劝阻我不要使用 x86 程序集,请不要,我有非常特殊的原因为什么要在 x86 程序集中构建它!)

我正在尝试构建一个 vtable 以在我的 COM 对象中使用,但我不断收到奇怪的指针,而不是指向我的函数的实际指针。(我在想我得到了相对偏移量,或者 NASM 在其中嵌入了临时值,并且在链接期间它们没有被实际值替换)

我目前正在尝试构建的接口是IClassFactory接口,代码如下:

注意:这不是所有代码,我在不同的文件中有 DllGetClassObject、DllMain 等。

但是当我组装(使用 NASM: nasm -f win32 comobject.asm)和链接(使用 MS Link: link /dll /subsystem:windows /out:comobject.dll comobject.obj),并使用 OllyDbg 检查可执行文件时,vtable 会出现奇怪的值。例如,在我上次构建中,函数的实际地址如下:

  • 查询接口 - 0x00381012
  • AddRef - 0x0038101A
  • 发布 - 0x00381020
  • 创建实例 - 0x00381026
  • LockServer - 0x0038102E

但是 vtable 有这些值:

  • 查询接口 - 0x00F51012
  • AddRef - 0x00F5101A
  • 发布 - 0x00F51020
  • 创建实例 - 0x00F51026
  • 锁定服务器 - 0x00F5102E

这些值看起来非常可疑......几乎就像搬迁没有采取一样。此外,vtable 显示为 0x00F5104A,所有这些都是不可访问的内存地址。(出于信息目的,这些值每次都不同

我尝试使用 Visual Studio 2010 Express 在 C++ 中做同样的事情,一切都很好。所以我假设这只是我在装配中缺少的东西......


谁能向我指出为什么这些值没有正确显示?

0 投票
2 回答
4895 浏览

c++ - 一个类的对象(使用单/多继承)将有多少个 vptr?

一个对象的 clas(child) 与一个多重继承 base1 和 base2 的基类具有单继承关系,通常需要多少个 vptr。确定一个对象提供了多少个 vptr 的策略是什么,它具有一对单继承和多继承。虽然标准没有具体说明 vptrs 但我只想知道一个实现是如何实现虚拟功能的。

0 投票
2 回答
1378 浏览

c++ - DLL 导出的类的 vtable 布局不正确:请求澄清有关标头和 vtable 构造的信息

尽管手头的问题已经解决,但对于使用什么数据来构造类的 vtable 以及 vtable 的布局存储在哪里,我还是有点困惑。如果有人可以提供澄清或指出一些可能满足我好奇心的信息,我将不胜感激。

背景

  1. 两个独立的 VC6.0 项目:一个用于 exe,一个用于 dll。
  2. 应用程序包含来自 dll 项目版本的 .lib、.dll 和 .h 文件。
  3. 当新版本准备就绪时,.lib、.dll 和 .h 文件将从 dll 项目复制到 exe 项目中。
  4. 我继承了这个方案。

问题:

我最近对 ​​DLL 进行了更改并复制了 .lib 和 .dll 但忘记复制头文件。层次结构发生了一些变化,因此,一个特定类(称为它InternalClass)的 vtable 发生了变化。

exe 不会直接调用InternalClass. 相反,它创建了一个不同类的实例(称为它InterfaceClass),它封装了一个指向InternalClass对象的指针并针对该指针调用各种方法。

在运行时,从InterfaceClass方法内部对InternalClass方法的调用实际上是在调用错误的方法(即InterfaceClass会调用InternalClass::AInternalClass::B实际运行)。查看asm,事实证明 fixup 或 thunk(如果这是错误的行话,我很抱歉!)正在使用正确的偏移量到 vtable 中。但是,vtable 本身包含您希望从头文件中获得的指针列表。

实际问题:

我意识到我的错误,将头文件复制过来,重新编译,一切都很好。然而,我留下了一个挥之不去的问题:

何时确定 vtable 的布局以及在运行时使用哪些信息为这些类构建 vtable?也就是说,在我看来,在编译 dll 时必须已经组装了正确的vtable,以便偏移量等可以用于从InterfaceClassto的调用InternalClass。那么,为什么在运行时使用过时的 vtable 呢?使用它拥有的头文件编译exe时,布局是否单独确定?

我不确定这是否完全清楚。让我知道我的要求是否过于复杂。谢谢!

0 投票
2 回答
3823 浏览

c++ - 虚拟功能对象切片

我的问题是参考这个问题,它解释了在对象切片的情况下虚拟函数如何工作,最终调用基类虚拟函数和维基百科文章,它解释了下面代码的派生类的虚拟表布局

上面的程序输出 "In A::func" 。

但是如果没有 B 类的虚拟表知道基类 A::func 怎么会最终调用 A::func

0 投票
3 回答
39041 浏览

c++ - 什么是 C++ 中的 vtable

可能重复:
为什么我需要虚拟表?

什么是 C++ 中的 vtable?

到目前为止,我知道 vtable 是一个虚拟表,它有一个指向虚拟函数的指针数组。有没有我可以阅读的带有实际实现示例的文章?(任何演练将不胜感激。)

0 投票
4 回答
3349 浏览

c# - c++ 和 c# 中的 vtables 是如何实现的?

让我们有这种情况(在 c++ 中,在 c# 中,类 A、B 是接口):

c# 编译器是否总是创建一个 vtable?投射时是否会进行任何指针修复?

0 投票
2 回答
789 浏览

c++ - C++ v-table:部分语言或编译器依赖?

v-table(虚拟方法表)是 C++ 规范的一部分,还是由编译器来解决虚拟方法查找?

如果它是规范的一部分:为什么?

我猜它依赖于编译器,但有人对我说它是规范的一部分。

非常欢迎参考!

0 投票
1 回答
4442 浏览

c++ - COM 对象函数上的 API 挂钩?

问候 StackOverflowians,

正如在此处发现的那样,Windows 7 存在一个错误,在该错误中,Windows Explorer 实例不会触发 DISPID_BEFORENAVIGATE2 事件。此事件允许在导航即将发生时通知 shell 扩展,并且(对我来说最重要的是)有机会取消导航。很长一段时间以来,我一直在寻找一种解决方法,我想我找到了。但是,我想就它的安全性提出一些意见。

最近我一直在使用 API 挂钩,并且我已经在使用它为我的扩展挂钩一些函数。我注意到IShellBrowser中有一个控制导航的函数。起初我认为你不能挂钩这样的东西,但在阅读了 COM 对象的布局后,我意识到这应该可以通过从任何活动实例的 vtable 中获取正确的函数指针来实现。果然,它就像一场梦。设置钩子后,所有资源管理器窗口中的所有导航都直接通过我的 detour 函数运行,我可以根据它们的目标 pidl 决定是否拒绝它们。

所以我的问题是,有什么理由我不应该这样做吗?我从未听说过用于挂钩 COM 对象函数的 API 挂钩。有没有它不起作用的情况?危险吗?(至少比常规的 API 挂钩)

相关代码如下。我正在使用MinHook,这是一个简约的挂钩库,它使用了久经考验的蹦床函数方法。

0 投票
3 回答
712 浏览

c++ - 一个基类如何使用另一个父类的函数来满足一个父类的纯虚函数的定义

我正在扩展一个现有的 C++ 项目。我有一个派生自两个父类的基类。其中一个父母有一个纯虚函数。我希望该纯虚函数由另一个父级中实现的函数定义。

所以,我希望另一个父类满足基类定义父类纯虚函数的义务。我尝试了两种方法,都导致编译器错误。
有任何想法吗?

这是一个展示我的第一个想法的 C++ 程序,希望编译器只base2使用vfunc().

编译器报告它derived仍然是一个抽象类:

这是我的第二次尝试:

我实际上希望这能为我做这件事,但链接器却给了我一堆我不明白的 vtable 错误:(Mac OS 10.6,gcc 4.2.1)