.NET跨平台之旅:corehost 是如何加载 coreclr 的

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

corehost

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

在 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 模式。github

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):json

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)的句柄。spa

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

找到 coreclr 库文件所在的位置,打开它,调用它的 coreclr_initialize() 方法,corehost 加载 coreclr 就这么简单。若是你有兴趣,能够用 C++ 写一个本身的 corehost 。code

开源的 .NET 变得更有意思,即便没有任何文档,即便没有正式发布,你也能够经过源码学习它,了解它。htm

相关文章
相关标签/搜索