如何读.Net Framework 的源码?

news2024/9/19 8:16:56

.Net Framework的源码可以从这里下载

Download

也可以在线直接浏览

https://referencesource.microsoft.com

这里我们以System.IO.Directory.CreateDirectory函数为例,来说明如何去读.Net Framework的源码。

在ReferenceSource在线界面的搜索框里输入Directory.CreateDirectory

在列表中选择Directory.CreateDirectory(System.String)重载,在右边可以看到实现的源码 

 可以看到在函数的最后调用了一个InternalXXX的函数,然后一直往下级找,可以找到Win32Native.CreateDirectory(name,secAttrs)这样一句代码。

这一句代码就是实现创建文件夹的核心,转到Win32Native类,可以看到这里面导入了大量的WinAPI函数。而Win32.CreateDirectory函数实际 上就是调用了Windows API函数CreateDirectory。

至此,我们就知道了.Net Framework中创建文件夹实际上还是调用的Windows API函数。

这也就是解释了为什么.Net Framework不能跨平台的原因,因为大部分功能的实现都是借助API函数的,脱离 了Windows系统,这些函数就用不了了。

在.Net Core中,这些API全部被重写了,所以.Net Core能支持跨平台了。

下面我们以一个复杂一点的情况,来说明一下如何查找这些InternalXXX函数的实现。这个分析的过程会比较长,需要你耐心的看完。

这里我们以System.Threading.Thread.Start()函数为例,该函数的作用是创建一个线程并启动。在Win32编程里,创建线程是调用的CreateThread API函数。在.Net Framework中,实际上也是调用的这个函数,只是做了多层封装。

在referencesource.microsoft.com搜索Thread.Start

 在右边的源码中可以看到,在Thread.Start函数的最后调用了一个叫StartInternal的函数,这是一个导出函数,在这里我们看不到这个函数源码。因为这些是在cli中实现的。

 

我在github上找到一个cli的2.0的源码,其它.Net Framework版本对应的cli代码官方并没有公开。GitHub - SSCLI/sscli20_20060311: Version: 2.0 Date Published: 3/23/2006. The Shared Source CLI is a compressed archive of the source code to a working implementation of the ECMA CLI and the ECMA C# language specification. This implementation builds and runs on Windows XP.。虽然是2.0的,但是并不影响我们深入了解.Net Framework的内部实现。

新版本的.NET平台cli源码是公开的。包括.Net Core 3.1 .NET 5 .NET 6等。GitHub - dotnet/runtime: .NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.

这部分的实现是C++语言,需要一定的C++基础。

我们在shared-source-cli-2.0中搜索StartInternal函数,可以看到这个函数实际 上是调用了ThreadNative的静态函数Start

我们在Core/CLR/vm/comsynchronizable.cpp中找到ThreadNative类中的 Start函数,源码如下:

 1 FCIMPL1(void, ThreadNative::Start, ThreadBaseObject* pThisUNSAFE)
 2 {
 3     ...
 4     StartInner(pThisUNSAFE);
 5     ...
 6 }
 7 
 8 void ThreadNative::StartInner(ThreadBaseObject* pThisUNSAFE)
 9 {
10     ...
11         BOOL success = pNewThread->CreateNewThread(
12                                         pNewThread->RequestedThreadStackSize() /* 0 stackSize override*/,
13                                         KickOffThread, share, nativeThreadName);
14    ...
15 }

可以看到这里实际 上是调用了Thread类的成员函数CreateNewThread来创建线程,我们在clr/src/vm/threads.cpp中找到CreateNewThread函数。

 1 BOOL Thread::CreateNewThread(SIZE_T stackSize, LPTHREAD_START_ROUTINE start, void *args)
 2 {
 3    ...
 4     if (!CLRTaskHosted()) {
 5         bRet = CreateNewOSThread(stackSize, start, args);
 6     }
 7     else {
 8         bRet = CreateNewHostTask(stackSize, start, args);
 9     }
10 
11     ...
12 }

CreateNewThread里面有一个分支,判断是调用CreateNewOsThread还是CreateNewHostTask,这里我以CreateNewOsThread为例,在threads.cpp中找到CreateOsThread函数,如下

 1 BOOL Thread::CreateNewOSThread(SIZE_T sizeToCommitOrReserve, LPTHREAD_START_ROUTINE start, void *args)
 2 {
 3     ...
 4     h = ::CreateThread(NULL     /*=SECURITY_ATTRIBUTES*/,
 5                        sizeToCommitOrReserve,
 6                        intermediateThreadProc,
 7                        lpThreadArgs,
 8                        dwCreationFlags,
 9                        &ourId);
10 
11    ...
12 }

在这个函数里可以看到创建线程的核心代码,就是调用CreateThread。

至此,我们也就完整的了解了.Net Framework中Thread.Start()函数的整个实现过程。这其中还有多层封装,我这里不做详细介绍,我这里只是告诉大家如何如何从上层封装找到底层调用。有了这个方法,其它 的.Net API都可以去看一下它到底是怎么实现的。

很早以前就用.Net Reflector去看.Net的源码,但是每次碰到内部调用,就没有办法深入了解了,最近也是一次偶然的机会,我知道 了这些内部调用是在cli中实现的,而cli的最新源码也是开源 的,所以才有了这篇文章。

但这里要提一句的是,Windows API内部是如何实现的,这个我没有去了解过,以我现在的能力,估计也理解不了内部的实现逻辑,如果有小伙伴略懂一二,也可以在下面的评论教 教 我。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言深度剖析--不定期更新的第四弹

哈哈哈哈哈哈,今天一天两更! void关键字 void关键字不能用来定义变量,原因是void本身就被编译器解释为空类型,编译器强制地不允许定义变量 定义变量的本质是:开辟空间 而void 作为空类型,理论上不应该开…

NLP自然语言处理学习过程中知识点总结

OOV是什么 OOV 是 “Out Of Vocabulary”的缩写,意思是 “超出词汇表” 或 “未登录词汇”。 在自然语言处理 (NLP) 中,OOV 指的是模型训练时没有见过的词语或词汇。通常,语言模型会为其训练数据中未出现的词汇分配一个特殊的标记。OOV 词汇…

【国赛急救包】数模国赛查重规则及降重技巧

国赛已经快接近尾声了,各位宝宝论文写得怎么样啦~ 今天为大家分享关于国赛查重的一些规则,以及降重技巧!快收藏起来吧~ 1. 国赛查重要求及如何查重 • 数学建模国赛的查重除了知网数据库以外,更重要的是自建库的查重比对&#x…

14.1 为什么说k8s中监控更复杂了

本节重点介绍 : k8s中监控变得复杂了,挑战如下 挑战1: 监控的目标种类多挑战2: 监控的目标数量多挑战3: 对象的变更和扩缩特别频繁挑战4: 监控对象访问权限问题 k8s架构图 k8s中监控变得复杂了,挑战如下 挑战1: 监控的目标种类多 对象举例 podnodese…

【kubernetes】配置管理中心Configmap运用

一,介绍 Configmap(简写 cm)是k8s中的资源对象,用于保存非机密性的配置的,数据可以用key/value键值对的形式保存,也可通过文件的形式保存。 【局限性】:在ConfigMap不是用来保存大量数据的&am…

Windows下Python和PyCharm的应用(二)__快捷键方式的设定

前言 程序写久了,难免会形成自己的编程习惯。比如对某一套快捷键的使用,已经形成了肌肉记忆。 为了方便快捷键的使用,可以在PyCharm中设置自己喜欢的快捷键。 我比较习惯于微软Visual Studio的快捷键设置。(因为早些年VC开发用的…

模具要不要建设3D打印中心

随着3D打印技术的日益成熟与广泛应用,模具企业迎来了自建3D打印中心的热潮。这一举措不仅为企业带来了前所未有的发展机遇,同时也伴随着一系列需要克服的挑战,如何看待企业引进增材制造,小编为您全面分析。 机遇篇: 加…

win11如何录屏

在 Win11 中录屏可以使用系统自带的工具和一些第三方应用。以下是几种方法: 方法一:使用 Xbox Game Bar 1. 打开 Xbox Game Bar - 按 Win G 组合键打开 Xbox Game Bar。 2. 开始录制 - 在显示的界面中,点击“录制”按钮(…

Linux之nginx部署项目【前后端分离】(外加redis安装)

nginx安装和访问 1.使用apt安装Nginx apt install -y nginx 用whereis nginx找到和nginx相关目录 nginx目录结构 /usr/sbin/nginx 服务文件 /etc/nginx 配置目录 /usr/share/nginx/html 发部项目 服务名: nginx.service ps -ef | grep nginx apt install -y net-tools …

【Excel 表打印基本操作】

表格打印 1.设置缩放打印1.1 命令启动器、命令组1.2 一页纸打印1.3 自由设置打印缩放比例 2.跨页打印标题3.打印选定区域3.1 打印前/后n行3.2 打印多个表格区域3.3 只打印图表3.4 不打印照片 4.设置分页打印4.1 手动分页:分页预览,分页符a) 手动插入分页…

x86的Docker环境下载ARM版容器镜像

文章目录 应用场景下载方法 应用场景 内网是信创ARM环境,需要从外网下载镜像,但外网的docker环境是X86环境,此时需要在外网docker环境下载ARM版容器镜像。 下载方法 # 如何找sha256参见下面的截图。 # hub.docker网站找到镜像后&#xff0…

插件maven-search:Maven导入依赖时,使用插件maven-search拷贝需要的依赖的GAV

然后粘贴&#xff1a; <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency>

0基础学习爬虫系列:程序打包部署

1.目标 将已经写好的python代码&#xff0c;打包独立部署或运营。 2. 环境准备 1&#xff09;通义千问 &#xff1a;https://tongyi.aliyun.com/qianwen 2&#xff09;0基础学习爬虫系列–网页内容爬取&#xff1a;https://blog.csdn.net/qq_36918149/article/details/14199…

【Python篇】PyQt5 超详细教程——由入门到精通(终篇)

文章目录 PyQt5超详细教程前言第9部分&#xff1a;菜单栏、工具栏与状态栏9.1 什么是菜单栏、工具栏和状态栏9.2 创建一个简单的菜单栏示例 1&#xff1a;创建带有菜单栏的应用程序代码详解&#xff1a; 9.3 创建工具栏示例 2&#xff1a;创建带有工具栏的应用程序代码详解&…

如何在mac上玩使命召唤手游?苹果电脑好玩的第一人称射击游戏推荐

《使命召唤4&#xff1a;现代战争》&#xff08;Call of Duty 4: Modern Warfare&#xff09;是由Infinity Ward开发并于2007年发行的第一人称射击游戏。该游戏是《使命召唤》系列的第四部作品&#xff0c;是一款非常受欢迎的游戏之一&#xff0c;《使命召唤4&#xff1a;现代战…

QT串口读取Serial->readAll()踩过的坑

QT串口读取Serial->readAll接收不完全踩过的坑 Chapter1 QT串口读取Serial->readAll()踩过的坑坑一&#xff1a;坑二 Chapter2 [QT串口上位机BUG解决]json解析数据bug以及接收数据问题问题描述原因分析&#xff1a;解决方案&#xff1a;一、是数据采集端&#xff08;单片…

灰光模块,彩光模块-介绍

1. 引用 知识分享系列一&#xff1a;5G基础知识-CSDN博客 5G前传的最新进展-CSDN博客 灰光和彩光_通信行业5G招标系列点评之二&#xff1a;一文读懂5G前传-光纤、灰光、彩光、CWDM、LWDM、MWDM...-CSDN博客 ADOP带你了解&#xff1a;CWDM、DWDM、MWDM、LWDM&#xff1a;快速…

久久公益节||“携手万顺叫车一起做公益”

99公益日是由腾讯公益联合多家公益组织、企业及社会各界爱心人士共同举办的年度大型公益活动。随着99公益日的到来&#xff0c;同悦社工诚挚地邀请了万顺叫车一起参与今年的公益活动&#xff0c;共同为社会公益事业贡献力量。 在本次公益倡导活动中&#xff0c;万顺叫车将发挥其…

vLLM (5) - LLMEngine下篇

系列文章目录 vLLM (1) - Qwen2推理&部署 vLLM (2) - 架构总览 vLLM (3) - Sequence & SequenceGroup vLLM (4) - LLMEngine上篇 vLLM (5) - LLMEngine下篇 文章目录 系列文章目录前言一、类图二、LLM._validate_and_add_requests()1.LLM2.LLMEngine3.Scheduler 三、L…

颠覆你的开发模式:敏捷思维带来的无限可能

敏捷软件开发作为现代软件工程的重要方法论&#xff0c;强调快速响应变化和持续交付价值。通过灵活的开发模式和高效的团队协作&#xff0c;敏捷方法在应对动态变化和不确定性方面表现出色。本文将结合学习和分析&#xff0c;探讨系统变化对敏捷开发的影响、业务与技术的对齐以…