这篇文章主要介绍了C#中方法重载实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#中方法重载实例分析文章都会有所收获,下面我们一起来看看吧。最近在看 C++ 的方法重载,我就在想 C# 中的重载底层是怎么玩的,很多朋友应该知道 C 是不支持重载的,比如下面的代码就会报错。从错误信息看,它说say
方法已经存在了,尴尬。。。要想寻找答案,需要了解一点点底层知识,那就是编译器在编译 C 方法时会将函数名作为符号添加到符号表中,这个符号表就是call到say方法字节码中间的一个载体,画个图大概就是这样。简而言之,call 先跳转到符号表, 然后再 jmp 到 say 方法,问题就出现在这里,符号表是一种类字典结构,是不可以出现符号相同的情况。对了,在 windbg 中我们可以用x
命令去搜索这些符号,为了论证我的说法,可以在汇编层面给大家验证下,修改代码如下:接下来再看下汇编。知道了原理后,我们再看看 C++ 是如何在符号表上实现唯一性突破。为了方便讲述,我们先上一段 C++ 方法重载的代码。按理说sayhello
有多个,肯定是无法突破的,带着好奇心我们看下它的反汇编代码。从汇编代码看, 调的都是Person::sayhello
这个符号,奇怪的是他们属于不同的地址:03B13A2h
,03B1302h
,这就太奇怪了,哈哈,字典类符号表肯定是没有问题的,问题是Visual Studio 20222
的反汇编窗口在调试时做了一些内部转换,算是蒙蔽了我们双眼吧,真是可气!!!居然运行时汇编代码都还不够彻底,那现在我们怎么继续挖呢? 可以用IDA
去看这个程序的静态反汇编代码,截图如下:从代码上的注释可以清楚的看到,原来:Person::sayhello(int)
变成了j_?sayhello@Person@@QAEXH@Z
。Person::sayhello(char const *)
变成了j_?sayhello@Person@@QAEXPBD@Z
到这里终于搞清楚了,原来 C++ 为了支持方法重载,将方法名做了重新编码,这样确实可以突破符号表的唯一性限制。我们都知道 C# 的底层 CLR 是由 C++ 写的,所以大概率玩法都是一样,接下来上一段代码:由免费云主机域名于 C# 的方法是由JIT
在运行时动态编译的,并且首次编译方法会先跳转到 JIT 的桩地址,所以断点必须下在第二次调用Say(10)
处才能看到方法的符号地址,汇编代码如下:从输出信息看,同样也是两个符号表地址,然后由符号表地址 jmp 到最后的方法体。关于“C#中方法重载实例分析”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C#中方法重载实例分析”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注百云主机行业资讯频道。
相关推荐: react安装yarn一直报不是内部命令如何解决
这免费云主机域名篇文章主要介绍了react安装yarn一直报不是内部命令如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇react安装yarn一直报不是内部命令如何解决文章都会有所收获,下面我们一起来看看吧。 react安装…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。