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 ...
随机推荐
- Docker-CE 安装(centos7)
配置yum源 > cd /etc/yum.repos.d/ > mkdir repo_bak > mv *.repo repo_bak/ > wget http://mirro ...
- python算法与数据结构-队列(44)
一.队列的介绍 队列的定义:队列是一种特殊的线性表,只允许在表的头部(front处)进行删除操作,在表的尾部(rear处)进行插入操作的线性数据结构,这种结构就叫做队列.进行插入操作的一端称为队尾,进 ...
- GRPC Oauth IdentityServer4
Server端 StartUp类: using System; using System.Collections.Generic; using System.Linq; using System.Th ...
- Hash碰撞概率
计算Hash冲突的概率 虽然已经很多可以选择的Hash函数,但创建一个好的Hash函数仍然是一个活跃的研究领域.一些Hash函数是快的,一些是慢的,一些Hash值均匀地分布在值域上,一些不是.对于我们 ...
- Egret入门学习日记 --- 第四篇
第四篇(学习篇) 好了,今天继续把昨天的问题解决了. 今天见鬼了. 现在界面又出来了.唯一我动过的地方,应该就是这里: 是的,我点了一下刷新.之后,不管我怎么创建新的EXML文件,放在src目录,还是 ...
- VMware下的Centos7实践Kvm虚拟化(通俗易懂)
虽然网上已经有很多关于kvm安装的教程了,但我还是看得头晕,有的教程里安装的包很多,有的很少,也没说明那些安装包的作用是干嘛的,用的命令也不一样,也没解释命令的意思是什么. 我重新写一个教程,尽量通俗 ...
- springmvc上传文件踩过的坑
@RequestMapping("/addTweet") public String addTweet(TweetVO tweetVO, HttpServletRequest re ...
- React躬行记(8)——样式
由于React推崇组件模式,因此会要求HTML.CSS和JavaScript混合在一起,虽然这与过去的关注点分离正好相反,但是更有利于组件之间的隔离.React已将HTML用JSX封装,而对CSS只进 ...
- [Haoi2016]放棋子 题解
4563: [Haoi2016]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 285[Submit][Status] ...
- <a>标签 IOS 安卓 亲测有效
一.普通链接 <a href="http://www.baidu.com">百度</a> 二.邮件链接 1.标签最简式 <a href="m ...