vfptr 中的 Visual C++ 方法按相反顺序排列

2023-12-02

有没有办法控制 vfptr 中某些类方法的顺序?看来Visual C++ 2010至少将方法指针按照声明顺序排列,重载方法除外。下面是示例代码:

enum ENUM {
};

class CLASS {
    virtual void foo1() { };
    virtual CLASS& __cdecl operator<<(const ENUM x) { return *this; };
    virtual void foo2() { };
    virtual CLASS& __cdecl operator<<(const char* x) { return *this; };
    virtual CLASS& __cdecl operator<<(int x) { return *this; };
    virtual void foo3() { };
    virtual void foo1(int x) { };
};

int main() {
    CLASS c;
    return 0;
}



上面的代码生成以下vfptr:

[0] 0x00e21091 CLASS::foo1(int) *
[1] 0x00e2100a CLASS::foo1(void)    *
[2] 0x00e211ae CLASS::operator<<(int)   *
[3] 0x00e21050 CLASS::operator<<(char const *)  *
[4] 0x00e211db CLASS::operator<<(enum ENUM) *
[5] 0x00e2106e CLASS::foo2(void)    *
[6] 0x00e21172 CLASS::foo3(void)    *



因此,重载方法被分组到第一个这样的声明,然后反转。将它们分组在一起不是问题,因为我可以轻松地将它们分组在头文件中。然而,相反的顺序是一个问题,因为不同的编译器显然不会这样做,这意味着它们会调用错误的方法。这与在应用程序和 DLL 之间传递对象指针有关。
首先,我希望 MSVC 对重载方法有一个首选顺序,因此我尝试按照 MSVC 在 vfptr 中的顺序声明这些方法,但随后它又简单地反转了它们,以下是代码和结果:

class CLASS {
    virtual void foo1(int x) { };
    virtual void foo1() { };
    virtual CLASS& operator<<(int x) { return *this; };
    virtual CLASS& operator<<(const char* x) { return *this; };
    virtual CLASS& operator<<(const ENUM x) { return *this; };
    virtual void foo2() { };
    virtual void foo3() { };
};


result:

[0] 0x0113100a CLASS::foo1(void)    *
[1] 0x01131091 CLASS::foo1(int) *
[2] 0x011311db CLASS::operator<<(enum ENUM) *
[3] 0x01131050 CLASS::operator<<(char const *)  *
[4] 0x011311ae CLASS::operator<<(int)   *
[5] 0x0113106e CLASS::foo2(void)    *
[6] 0x01131172 CLASS::foo3(void)    *



我想使用方法重载,至少有一种我可以使用的技巧(知道 MSVC 将使用的顺序,使用该顺序创建新标头以便仅由 DLL 使用),但我宁愿让它正常工作首先。或者说这完全有可能吗?


即使使用不同的编译器,您也可以在模块之间使用 C++ 接口,但您刚刚遇到了边缘情况。以下是接口可以跨不同编译器工作的原因:可用的 C++ 编译器必须生成可与 COM 接口一起工作的代码。 COM 对象看起来很像具有单个 vtable 的 C++ 对象,其指针位于对象的偏移量零处。问题是,据我所知,COM 没有为重载方法定义任何规则,但只要您不想利用方法重载以及其他一些外来语言功能,那么您就可以信任方法顺序(因为 COM兼容性)。

即使您不在模块之间使用 C++ 接口,模块之间的接口也应该相当简单。我从来没有迫切需要模块之间的接口中的方法重载。即使您需要重载,您也可以为方法指定单独的名称,就像根本没有重载的语言一样。在模块之间传递基本类型和简单数据结构也是明智的,如果仅传递基本类型,那么很容易编译具有不同配置的模块(例如“调试”中的一个和“发布”中的其他配置)以加快调试迭代。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vfptr 中的 Visual C++ 方法按相反顺序排列 的相关文章

  • 创建 DirectoryEntry 实例以供测试使用

    我正在尝试创建 DirectoryEntry 的实例 以便可以使用它来测试将传递 DirectoryEntry 的一些代码 然而 尽管进行了很多尝试 我还是找不到实例化 DE 并初始化它的 PropertyCollection 的方法 我有
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐

  • 从 WCF 服务公开枚举的 DescriptionAttribute

    如何使用 WCF 将服务中的枚举值中的描述属性暴露给客户端或 Web 引用 或者 如何使用 WCF 向客户端公开带有描述属性的枚举 虽然公开描述属性不公开 但客户端中仅公开枚举值 我想要枚举中描述属性的值 您不能强制执行此操作 mex WD
  • 如何在没有类的情况下生成对象的新实例?

    问题 如何从该类的实例生成该类的新实例 我发现了什么 考虑下一个类及其实例 Create a new class var Foo function Foo console log New instance of FOO Foo protot
  • 我可以隐藏控制器并查看名称 cake php 2 吗?

    我正在使用 cake php 由于某种原因我想从 url 中隐藏控制器和操作名称 当前网址我们喜欢 http 192 168 1 31 home this is test 其中 home 是控制器名称 this is test是动态的 sl
  • 进程卡在退出处,显示为僵尸但无法收获

    我有一个由其父级监控的进程 孩子遇到了一个错误 导致它调用abort 该进程不会篡改中止进程 因此它应该按预期进行 转储核心 终止 父级应该检测子级的终止并触发一系列事件来响应失败 子进程是多线程且复杂的 这是我看到的ps F UID PI
  • 查询失败错误:无法通过前缀查询视图。匹配视图的部分列表是

    我正在尝试查询具有多个表和等效视图的数据集 我试图使用 table suffix 仅查询表 但它返回错误 查询失败错误 无法通过前缀查询视图 匹配视图的部分列表 我无法从数据集中删除视图 有没有办法只查询表而忽略视图 SELECT COUN
  • 为什么 ref 和 out 不足以消除 C# 中重载的歧义?

    例如 为什么这个方法Max ref int x ref int y 不被认为是过载Max int x int y 为什么与相同out 这个问题预设了一个错误的前提 Max int x int y Max ref int x ref int
  • CreateProcess() C++ 文件未找到

    我正在尝试使用CreateProcess启动一个子进程 但是我不断得到error 2 根据文档 该文件未找到 我的代码如下所示 if CreateProcess LPCTSTR test exe NULL NULL NULL FALSE 0
  • 如果单词至少包含 N 次,则匹配正则表达式

    尝试创建 SpamAssassin 自定义规则 如果电子邮件正文中包含短语 SEO 四次或更多次 则该规则会匹配 为什么像这样的简单模式不匹配 true SEO 4 m 我想我明白了 您不需要 m 修饰符 因为您不使用 或 您需要 s 修饰
  • PyQT4 和 QPixmap:加载大小为零的图像?

    我对 PyQt4 感到困惑 我在python2 6上尝试了以下步骤 In 1 from PyQt4 import QtGui In 2 import sys In 3 app QtGui QApplication sys argv In 4
  • 重写 onMeasure 时,自定义 LinearLayout 的膨胀子项不会显示

    我想展示一个MyCustomLinearLayout这延伸了LinearLayout 我正在充气MyCustomLinearLayout与android layout height match parent 属性 我想要的是展示一个Imag
  • 从文件中随机选择行

    我有一堆文件 每个文件都有 5 行标题 在文件的其余部分中 一对行形成一个条目 我需要从这些文件中随机选择条目 我如何选择随机文件和随机条目 一对行 不包括标题 如果文件足够小 请将行对读入内存并从该数据结构中随机选择 如果文件太大 Eug
  • PHP - 返回分隔符后的所有内容

    有similar 问题在SO中 但我找不到任何完全像这样的 我需要删除直到 并包括 特定分隔符的所有内容 例如 给定字符串File MyFile jpg 我需要删除所有内容 这样我就只剩下MyFile jpg 提前致谢 使用此 preg r
  • 从 IBDesignable 中的自定义控件的框架加载代码

    我已经在 OS X 应用程序中实现了一个运行良好的自定义控件 当绘制控件时 它使用来自非系统框架的代码 控件是用swift编写的 框架是用Objective C编写的 该框架不是与具有自定义控件的应用程序构建在同一项目或工作区中 我已将框架
  • 多行注释解决方法?

    我 某种程度上 已经知道这个问题的答案 但我认为这是 R 用户列表中经常被问到的问题 应该有一个可靠的好答案 据我所知 R 中没有多行注释功能 那么 有人有什么好的解决方法吗 虽然 R 中的相当多的工作通常涉及交互式会话 这让人怀疑是否需要
  • 按列值计算百分比

    我有以下有关瑞士注册车辆的数据框 Fuel Year Region Count Gasoline 2013 GE 169600 Diesel 2013 GE 46790 Hybrid 2013 GE 2268 Electric 2013 G
  • Pandas:计算列中所有匹配模式的出现次数

    假设我有一个数据框 df pd DataFrame column 1 ABC DEF JKL GHI ABC ABC ABC DEF GHI DEF DEF DEF ABC GHI DEF ABC column 2 9 2 3 4 6 2
  • i++、i=i+1 和 i+=1 哪个更快? [复制]

    这个问题在这里已经有答案了 我很好奇 想知道其中CPU运行速度最快的是哪一个i i 1 and i i 1我如何衡量它们的执行时间 嗯 最初人类发明了以下记录 i i 1 然后随着硬件方面的成就人类发明了以下记录 i 1 最后由于计算机科学
  • 使用 PHP 和正则表达式自定义 URL 路由

    我正在尝试创建一个非常简单的 URL 路由 我的思考过程是这样的 首先检查所有静态URL 然后检查数据库 URL 如果都不存在则返回404 当然 静态 URL 很容易实现 但我正在尝试找出实现动态 URL 的最佳方法 我宁愿不必设置静态前缀
  • SWIFT:为什么“NSURL(string:”返回 Nil,即使它是浏览器中的有效 URL?

    前两个示例链接有效 第三个链接返回 NIL 为什么 NSUrl 对于这样的字符串返回 nil 即使它在浏览器中是有效的 url 我应该更多地处理字符串吗 这是我的代码 import UIKit import Foundation class
  • vfptr 中的 Visual C++ 方法按相反顺序排列

    有没有办法控制 vfptr 中某些类方法的顺序 看来Visual C 2010至少将方法指针按照声明顺序排列 重载方法除外 下面是示例代码 enum ENUM class CLASS virtual void foo1 virtual CL