CoreCLR Host源码分析(C++)
废话不多说,直接上源码:
1.在托管程序集里面执行方法
HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,//通过CreateAppDomainWithManager创造的domainid
LPCWSTR pwzAssemblyPath,//要托管的.net core DLL 路径
int argc, //传递进来参数个数
LPCWSTR* argv,//传递进来参数数组
DWORD *pReturnValue)//指示函数执行的结果标记
{
CONTRACTL
{
THROWS; // Throws...as we do not want it to swallow the managed exception
ENTRY_POINT;
}
CONTRACTL_END; // This is currently supported in default domain only
if (dwAppDomainId != DefaultADID) //如果不等于默认defaultADID 直接返回失败标记
return HOST_E_INVALIDOPERATION; // No point going further if the runtime is not running...
if (!IsRuntimeActive() || !m_fStarted) //如果 coreclr host 没有在运行或者m_fstarted标记没有被启动,返回失败标记
{
return HOST_E_CLRNOTAVAILABLE;
} if(!pwzAssemblyPath) //如果托管的DLL为空,返回
return E_POINTER; if(argc < 0)//如果参数个数小于零,返回
{
return E_INVALIDARG;
} if(argc > 0 && argv == NULL)//如果参数个数大于零且参数数组等于零,返回
{
return E_INVALIDARG;
} HRESULT hr = S_OK; //初始化hr AppDomain *pCurDomain = SystemDomain::GetCurrentDomain(); //获取到当前appdomain的实例 Thread *pThread = GetThread(); //获取到当前进程指针
if (pThread == NULL) //如果进程指针为零
{
pThread = SetupThreadNoThrow(&hr);
if (pThread == NULL)
{
goto ErrExit;
}
} if(pCurDomain->GetId().m_dwId != DefaultADID)//如果当前进程的ID不等于defaultadid返回
{
return HOST_E_INVALIDOPERATION;
} INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
INSTALL_UNWIND_AND_CONTINUE_HANDLER; _ASSERTE (!pThread->PreemptiveGCDisabled()); Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath); //加载传递过来的托管程序集,并且实例化 #if defined(FEATURE_MULTICOREJIT)
pCurDomain->GetMulticoreJitManager().AutoStartProfile(pCurDomain);
#endif // defined(FEATURE_MULTICOREJIT) {
GCX_COOP(); // Here we call the managed method that gets the cmdLineArgs array.
SetCommandLineArgs(pwzAssemblyPath, argc, argv);//设置命令行参数 PTRARRAYREF arguments = NULL;
GCPROTECT_BEGIN(arguments); arguments = (PTRARRAYREF)AllocateObjectArray(argc, g_pStringClass);//分配内存
for (int i = 0; i < argc; ++i)
{
STRINGREF argument = StringObject::NewString(argv[i]);//转换参数
arguments->SetAt(i, argument);//设置参数数组标记
} DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /*waitForOtherThreads */); //执行需要托管的method
if (pReturnValue) //如果返回标记不为空
{
*pReturnValue = retval;//赋值
} GCPROTECT_END(); } UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
UNINSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP; ErrExit: //如果错误,调到errexit ,返回HR return hr;
}
2.利用非托管加载程序集
Assembly *AssemblySpec::LoadAssembly(LPCWSTR pFilePath) // 传递托管程序集路径
{
CONTRACT(Assembly *)
{
THROWS;
GC_TRIGGERS;
MODE_ANY;
PRECONDITION(CheckPointer(pFilePath));
POSTCONDITION(CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACT_END; AssemblySpec spec; //初始化assemblyspec 类
spec.SetCodeBase(pFilePath); //设置类的托管程序集路径
RETURN spec.LoadAssembly(FILE_LOADED); //设置类的加载方式为 文件加载
} DomainAssembly *AssemblySpec::LoadDomainAssembly(FileLoadLevel targetLevel, //加载方式,为文件加载,另外三个参数都为空
BOOL fThrowOnFileNotFound,
BOOL fRaisePrebindEvents,
StackCrawlMark *pCallerStackMark)
{
CONTRACT(DomainAssembly *)
{
INSTANCE_CHECK;
THROWS;
GC_TRIGGERS;
MODE_ANY;
POSTCONDITION((!fThrowOnFileNotFound && CheckPointer(RETVAL, NULL_OK))
|| CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACT_END; ETWOnStartup (LoaderCatchCall_V1, LoaderCatchCallEnd_V1); //初始化一些宏定义
AppDomain* pDomain = GetAppDomain(); //获取当前 appdomain 的实例 DomainAssembly *pAssembly = nullptr; //声明并赋值一个 domainassembly ICLRPrivBinder * pBinder = GetHostBinder(); //获取到 iclrprivbinder 对象 // If no binder was explicitly set, check if parent assembly has a binder.
if (pBinder == nullptr) //如果 pbinder等于零
{
pBinder = GetBindingContextFromParentAssembly(pDomain); //获取到父类和注入的一些方法
} if (pBinder != nullptr)//如果获取到了
{
ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
HRESULT hrCachedResult;
if (SUCCEEDED(pBinder->FindAssemblyBySpec(GetAppDomain(), this, &hrCachedResult, &pPrivAssembly)) &&
SUCCEEDED(hrCachedResult))//用pbinder找到appdomain 的pprivassembly
{
pAssembly = pDomain->FindAssembly(pPrivAssembly);//利用找到的pprivassembly,pdomain调用然后赋值给要返回的程序集
}
} if ((pAssembly == nullptr) && CanUseWithBindingCache()) //如果为空
{
pAssembly = pDomain->FindCachedAssembly(this);//pdomain带上当前类的实例去缓存里面找当前的程序集
} if (pAssembly)//如果找到
{
pDomain->LoadDomainFile(pAssembly, targetLevel); //以文件方式加载程序集
RETURN pAssembly; //然后返回
} PEAssemblyHolder pFile(pDomain->BindAssemblySpec(this, fThrowOnFileNotFound, fRaisePrebindEvents, pCallerStackMark));//如果上面所有步骤都不行,实例化一个peassemblyholder,
if (pFile == NULL)
RETURN NULL; pAssembly = pDomain->LoadDomainAssembly(this, pFile, targetLevel);//利用这个实例化的peassemblyholder和this指针,以及文件加载的方式去获取程序集 RETURN pAssembly; //返回程序集
}
CoreCLR Host源码分析(C++)的更多相关文章
- Orchard源码分析(5):Host相关(Orchard.Environment.DefaultOrchardHost类)
概述 Host 是应用程序域级的单例,代表了Orchard应用程序.其处理应用程序生命周期中的初始化.BeginRequest事件.EndRequest事件等. 可以简单理解为HttpApplicat ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- ABP源码分析七:Setting 以及 Mail
本文主要说明Setting的实现以及Mail这个功能模块如何使用Setting. 首先区分一下ABP中的Setting和Configuration. Setting一般用于需要通过外部配置文件(或数据 ...
- ABP源码分析三十五:ABP中动态WebAPI原理解析
动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...
- MyCat源码分析系列之——前后端验证
更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...
- gRPC源码分析0-导读
gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...
- YARN DistributedShell源码分析与修改
YARN DistributedShell源码分析与修改 YARN版本:2.6.0 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述 2 YARN Distrib ...
- [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)
对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...
- docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储
前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...
随机推荐
- Azkaban学习之路(二)—— Azkaban 3.x 编译及部署
一.Azkaban 源码编译 1.1 下载并解压 Azkaban 在3.0版本之后就不提供对应的安装包,需要自己下载源码进行编译. 下载所需版本的源码,Azkaban的源码托管在GitHub上,地址为 ...
- spring 5.x 系列第12篇 —— 整合memcached (代码配置方式)
文章目录 一.说明 1.1 XMemcached客户端说明 1.2 项目结构说明 1.3 依赖说明 二.spring 整合 memcached 2.1 单机配置 2.2 集群配置 2.3 存储基本类型 ...
- Apache配置URL重定向
Apache配置URL重定向 修改/etc/httpd/conf/httpd.conf文件的内容 <Directory "/var/www"> AllowOverrid ...
- (H5)canvas实现裁剪图片和马赛克功能,以及又拍云上传图片
1.核心功能 此组件功能包含: 图片裁剪(裁剪框拖动,裁剪框改变大小): 图片马赛克(绘制马赛克,清除马赛克): 图片预览.图片还原(返回原图.返回处理图): 图片上传(获取签名.上传图片). 2.核 ...
- select自定义下拉三角符号,css样式小细节
本来没有写文章的习惯,但是闲下来了,整理资料,发现还挺纠结,对前端来说.所以整理下,希望对看到的人有所帮助,毕竟我不是前端开发. 起因,是前端告诉我select 框的三角箭头不能自定义.但是第二次的时 ...
- 学Redis这篇就够了
Redis 简介 Redis 优势 Redis 数据类型 string hash list set Zset 小总结 基本命令 发布订阅 简介 实例 发布订阅常用命令 事务 实例 Redis 事务命令 ...
- c++学习书籍推荐《C++ Primer Plus中文版(第6版)》下载
百度云及其他网盘下载地址:点我 编辑推荐 一本经久不衰的C++畅销经典教程:一本支持C++11新标准的程序设计图书. 它被誉为“开发人员学习C++的教程,没有之一”! Amazon网站“Langua ...
- 分享几个能用的editplus注册码/2018年序列号
注册名:host1991 序列号:14F50-CD5C8-E13DA-51100-BAFE6 注册名:360xw 注册码:93A52-85B80-A3308-BF130-40412 ...
- 使用kubectl管理k8s集群(二十九)
前言 在搭建k8s集群之前,我们需要先了解下kubectl的使用,以便在集群部署出现问题时进行检查和处理.命令和语法记不住没有关系,但是请记住主要的语法和命令以及帮助命令的使用. 在下一篇,我们将讲述 ...
- 最新 centos7下zabbix 监控redis状态
准备 先准备两台服务器,已经部署好了zabbix-sever和zabbix-agent zabbix-server 192.168.1.70 centos7.2 zabbix-agent 192.16 ...