C++随笔:.NET CoreCLR之corleCLR核心探索之coreconsole(1)
一看这个标题,是不去取名有点绕呢?或者是,还有些问题?报告LZ...你的标题取得有问题,是个病句!↖(^ω^)↗!!!先不要急,其实我今天带给大家的就是CoreCLR中的coreclr。其中它是在名字叫HOST的一个子目录里面的。我的理解是HOST=宿主,GC因为是寄宿在WINDOWS中的,那么它是依靠什么寄宿呢,core-Console是我们狭义上的控制台吗?我觉得不是,我们可以把这个控制台理解为CoreCLR宿主的一个控制台,它控制了各个模块的调度,这全是我个人的理解。
这篇文章我也是采取随机抽取代码的方式来进行讲解,因为我自己也是变学边讲,我并不比大家懂得多多少,希望大家多能砸砸我的场子。大家可以看看,首先此文件引用了windows.h,那么它肯定是和我们的操作系统打交道的一个入口了。
我们来看看第一行代码,这其实可以表明几个知识点,第一,coreclr是基于“类”的,它不会轻易的实例化;第二点,coreclr是在runtime的时候改变其状态的;第三:Coreclr其实本身是让DLL转换成32位字符型的指针变量存储在内存中。
1 2 | // The name of the CoreCLR native runtime DLL. static const wchar_t *coreCLRDll = W( "CoreCLR.dll" ); |
那么我们再来找一个这个W("xxx")是什么,下面我的已经做了解释
1 2 3 4 5 6 7 8 9 10 11 12 13 | // This macro is used to standardize the wide character string literals between UNIX and Windows. // Unix L"" is UTF32, and on windows it's UTF16. Because of built-in assumptions on the size // of string literals, it's important to match behaviour between Unix and Windows. Unix will be defined // as u"" (char16_t) //定义的作用是标准化“宽字符”在Unix内核系统和Windows内核心态之间。 //Unix系统中,L""是UTF32,windows是UTF16.因为编译时就把它们定义成了不同的大小。 //Unix中,u""会被定义成char16_t类型 #ifdef PLATFORM_UNIX #define W(str) u##str #else // PLATFORM_UNIX #define W(str) L##str #endif // PLATFORM_UNIX |
StringBuffer是HostEnvironment的一个成员,来看看下面的代码,所以我认为,这里的StringBuffer,其实是和程序集有关系的,虽然我不知道有什么关系。
1 2 3 | // The list of paths to the assemblies that will be trusted by CoreCLR //程序集路径的集合将会被CoreCLR所信任 StringBuffer m_tpaList; |
下面我们还是先来看看这个StringBuilder吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | // Dynamically expanding string buffer to hold TPA list //动态扩展字符串缓冲区适应TPA动态列表 class StringBuffer { static const int m_defaultSize = 4096; //默认大小:4096个字节;4KB;1KB=1024字节 wchar_t * m_buffer; //最小缓冲区 size_t m_capacity; //最小区容量 size_t m_length; //最小字节长度 StringBuffer( const StringBuffer&); //带一个StringBuffer指针变量的构造函数 StringBuffer& operator =( const StringBuffer&); //定义一个重载操作符符,返回StringBuffer public : //无参构造函数,并初始化部分成员变量 StringBuffer() : m_capacity(0), m_buffer( nullptr ), m_length(0) { } //析构函数,释放缓冲区,注意析构函数是在程序结束时调用 ~StringBuffer() { delete [] m_buffer; } //返回已知缓冲区的指针变量的第一个节点的地址 const wchar_t * CStr() const { return m_buffer; } //是不是有点像.NET中StringBuilder里面的Append呢? void Append( const wchar_t * str, size_t strLen) { //如果m_buffer指向“空” if (!m_buffer) { //新建一个默认大小的数组,并分配给已知缓冲区 //这里之所以用数组,是因为空间可以理解为连续的空间。 m_buffer = new wchar_t [m_defaultSize]; //初始化缓冲区容量 m_capacity = m_defaultSize; } //如果最小长度+现有长度+单位长度比最小容积要大 if (m_length + strLen + 1 > m_capacity) { //2倍扩容 size_t newCapacity = m_capacity * 2; wchar_t * newBuffer = new wchar_t [newCapacity]; //这个函数我么见过,不过从字面上理解,应该是把以前的一些容量在内存中替换成新的容量 //PS(wcsncpy_s):Copy a wide - character string, to a maximum length //wcsncpy_s拷贝宽字符串,得到一个最大长度。 wcsncpy_s(newBuffer, newCapacity, m_buffer, m_length); //重新赋值 delete [] m_buffer; m_buffer = newBuffer; m_capacity = newCapacity; } //否则不扩容拷贝 wcsncpy_s(m_buffer + m_length, m_capacity - m_length, str, strLen); //每次执行以后,最小长度都会加上已经拷贝的长度 m_length += strLen; } }; |
有句话说得好,如果单单看一个问题,我们很难有深刻的记忆,所以当我讲解StringBuffer的时候,我打算“创新”一把,我会根据代码的上下文的应用来进行讲解。在192行左右有如下代码:
1 | if (!m_tpaList.CStr()) return false ; |
还有跟大家说一下为什么很多的变量都要定义成const的,因为这些东西只有在“运行时”的时候才可以改变。
1 2 3 4 | //返回已知缓冲区的指针变量的第一个节点的地址 const wchar_t * CStr() const { return m_buffer; } |
那么Append是怎么用的呢?是不是很像某个方法?(*^__^*) 嘻嘻……
1 2 | m_tpaList.Append(assemblyPath, assemblyPathLength); m_tpaList.Append(W( ";" ), 1); |
上面提到了TPA,我个人觉得应该是一些类似程序集生成的Dll文件的一个list集合,反正我也没查到,从网上,索性先这么理解吧。下面我们再来看一个东西:HostEnvironment,下面是部分成员变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // The path to this module //模块的路径 wchar_t m_hostPath[MAX_LONGPATH]; // The path to the directory containing this module //模块对应的物理目录的地址 wchar_t m_hostDirectoryPath[MAX_LONGPATH]; // The name of this module, without the path //模块对应的名字 wchar_t *m_hostExeName; // The list of paths to the assemblies that will be trusted by CoreCLR //程序集路径的集合将会被CoreCLR所信任 StringBuffer m_tpaList; |
这里面有一个很特别的成员,它是一个接口,是不是很神奇呢?C++也有接口。
1 | ICLRRuntimeHost2* m_CLRRuntimeHost; |
下面是定义:
1 | typedef interface ICLRRuntimeHost2 ICLRRuntimeHost2; |
大家也许对这个接口有一点小的疑问,为什么会有个2?有2,是不是有1呢?看下图,果然验证了我们的猜测。
下面我们来看看余下的2个成员变量:
1 2 3 4 5 | //HMODULE 是代表应用程序载入的模块,win32系统下通常是被载入模块的线性地址 --来自度娘 HMODULE m_coreCLRModule; //CoreCLR自带的日志系统 Logger *m_log; |
今天时间不早了,我也准备睡觉了,以后有空会继续和大家分享的哦。
__EOF__
作 者:ღKawaii
出 处:https://www.cnblogs.com/kmsfan/p/5507149.html
关于博主:一个普通的小码农,为了梦想奋斗
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!

出处:http://www.cnblogs.com/kmsfan
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
欢迎大家加入KMSFan之家,以及访问我的优酷空间!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
2015-05-18 简述ASP.NET MVC原理