前一篇博文中,在好奇心的驱使下,探秘了 dotnet run ,发现了神秘的 corehost  —— 运行 .NET Core 应用程序的幕后英雄。有时神秘就是一种诱惑,神秘的 corehost 让人产生了新的好奇心 —— corehost 是如何加载 coreclr 的?于是,“.NET跨平台之旅”开启了新的旅程 —— 带着这个疑问,游览 cli/src/corehost/

corehost 的入口是 corehost.cpp 的 main() ,进来后一条大道通向 corehost.run()

在 corehost.run() 中,首先调用的是 libhost.cpp 中的 detect_operating_mode() ,它根据 coreclr 所在的路径决定 corehost 的运行模式,有三种运行模式:muxer, standalone, split-fx。如果 corehost 与 coreclr 不在同一个文件夹,运行模式则是 muxer 。如果 corehost 与 coreclr 在同一个文件夹,并且文件夹下存在 .deps.json 文件或者不存在 .runtimeconfig.json 文件,则是 standalone 模式;否则是 split-fx 模式。

return ((pal::file_exists(own_deps_json)
|| !pal::file_exists(own_config_filename))
&& pal::file_exists(own_dll)) ?
host_mode_t::standalone : host_mode_t::split_fx;

dotent cli 默认使用的模式是 split-fx 模式,我们的示例站点 about.cnblogs.com 用的也是这种模式,通过下面的 tracing 信息可以看出来(export COREHOST_TRACE=2):

Checking if CoreCLR path exists=[/usr/share/dotnet-nightly/bin/libcoreclr.so]
Detecting mode... CoreCLR present in own dir [/usr/share/dotnet-nightly/bin] and checking if [corehost.deps.json] file present=[0]
Host operating in split mode; own dir=[/usr/share/dotnet-nightly/bin]

这次旅程也因此选择“split-fx 模式”这条游览路线。

针对 split-fx 模式,corehost.run() 接着会调用 hostpolicy.cpp 的 run() 方法(通过 corehost_init_t ),run() 方法中调用 deps_resolver.cpp 的 resolve_coreclr_dir() 解析 coreclr 所在的路径,然后调用 coreclr.cpp 的 bind()initialize() 方法加载 coreclr 。

在 bind() 方法中,根据之前解析出的 coreclr 路径,调用 pal.unix.cpp(针对的是Linux运行环境)的 load_library() 打开 coreclr 的库文件 libcoreclr.so (实际是调用 Linux 的 C 函数 dlopen() ),从而得到 coreclr 中3个函数(coreclr_initialize, coreclr_shutdown, coreclr_execute_assembly)的句柄。

在 initialize() 方法中,根据 bind() 中得到的句柄调用 coreclr 的 coreclr_initialize() 方法启动 coreclr , 加载 coreclr 的工作就这样完成了。

找到 coreclr 库文件所在的位置,打开它,调用它的 coreclr_initialize() 方法,corehost 加载 coreclr 就这么简单。如果你有兴趣,可以用 C++ 写一个自己的 corehost 。

开源的 .NET 变得更有意思,即使没有任何文档,即使没有正式发布,你也可以通过源码学习它,了解它。

.NET跨平台之旅:corehost 是如何加载 coreclr 的的更多相关文章

  1. webpack入坑之旅(五)加载vue单文件组件

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  2. 使用CEfSharp之旅(1) 加载网络页面

    原文:使用CEfSharp之旅(1) 加载网络页面 版权声明:本文为博主原创文章,未经博主允许不得转载.可点击关注博主 ,不明白的进群191065815 我的群里问 https://blog.csdn ...

  3. Aery的UE4 C++游戏开发之旅(4)加载资源&创建对象

    目录 资源的硬引用 硬指针 FObjectFinder<T> / FClassFinder<T> 资源的软引用 FSoftObjectPaths.FStringAssetRef ...

  4. .NET跨平台之旅:探秘 dotnet run 如何运行 .NET Core 应用程序

    自从用 dotnet run 成功运行第一个 "Hello world" .NET Core 应用程序后,一直有个好奇心:dotnet run 究竟是如何运行一个 .NET Cor ...

  5. .NET跨平台之旅:基于.NET Core改写EnyimMemcached,实现Linux上访问memcached缓存

    注:支持 .NET Core 的 memcached 客户端 EnyimMemcachedCore 的 NuGet 包下载地址:https://www.nuget.org/packages/Enyim ...

  6. .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点

    2016年7月10日,我们在生产环境中上线了第一个运行于Linux上的ASP.NET Core站点,这是一个简单的提供后端服务的ASP.NET Core Web API站点. 项目是在Windows上 ...

  7. .NET跨平台之旅:将QPS 100左右的ASP.NET Core站点部署到Linux服务器上

    今天下午我们将生产环境中一个单台服务器 QPS(每秒请求数)在100左右的 ASP.NET Core 站点部署到了 Linux 服务器上,这是我们解决了在 .NET Core 上使用 EnyimMem ...

  8. .NET跨平台之旅:生产环境中第2个跑在Linux上的ASP.NET Core站点

    今天我们在生产环境中上线了第2个跑在Linux上的ASP.NET Core站点.这是一个简单的Web API站点,通过命令行的方式调用安装在Linux服务器上的程序完成操作.之前用的是nodejs,现 ...

  9. .NET跨平台之旅:在Linux上以本地机器码(native)运行ASP.NET Core站点

    在将“.NET跨平台之旅”示例站点 about.cnblogs.com 从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0 (博文链接)之后,我们有一个难以抗拒的冲动 —— 体验 ...

随机推荐

  1. import matplolib 时出现"This probably means that tk wasn't installed properly."的解决方法

    最近又添了一台新电脑,配置好各个依赖环境后想用matplotlib画个图,结果报出下面的错误 根据报错分析,应该是C:/Python27/tcl/tk8.5/tk.tcl这个文件出问题了,根据图中的信 ...

  2. .net程序部署(setupFactory)

    vs 自带的安装打包 实在弱爆了,点都不好用.一直一直在寻觅一个靠谱点的打包工具.在网上寻寻觅觅 寻寻觅觅 功夫不负有心人,终于让我找到了.setupFactory  我用的是 8.0版本 . 首先要 ...

  3. QT 删除文件指定目录

    bool deleteDir(const QString &dirName) { QDir directory(dirName); if (!directory.exists()) { ret ...

  4. 说一说javascript跨域和jsonp

    同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议.域名.端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据. 要是想使用XMLHttpRequest或者常规 ...

  5. C#——this关键字(2,3)(含求助贴)

    这次来看一看this关键字的第二个用法:将对象作为参数传递到其他方法 ----------------------------------------------------------------- ...

  6. agsXMPP

    agsXMPP使用 agsXMPP中的例子已经有注册.登录.添加好友.接收好友添加请求.发送消息.接收消息等功能. 修改用户密码 登录后可用以下方法修改密码 IQ iq = new IQ(IqType ...

  7. EC笔记:第4部分:18、接口正确使用,不易被误用

    好的接口容易被正确使用,不易被误用 考虑以下函数: void func(int year,int month,int day){ //一些操作 } 这个函数看似合理,因为参数的名字已经暴露了它的用途. ...

  8. js picker webapp仿ios picker

    iosselect 在webapp下的一个picker组件 可以轻松实现各类选择器效果.比如地区选择 时间选择 日期选择等. 可以定制依赖关系,可以定制选择层级,可以定制高度 展示项数.无论你是px还 ...

  9. 解决motools和jquery之间的冲突

    在同一个页面需要同时使用motools和jquery,对于$,发生了冲突,以下是解决的办法. <head> <script src="./Scripts/lib/jquer ...

  10. js实现toggleClass