废话不多说,直接上源码:

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++)的更多相关文章

  1. Orchard源码分析(5):Host相关(Orchard.Environment.DefaultOrchardHost类)

    概述 Host 是应用程序域级的单例,代表了Orchard应用程序.其处理应用程序生命周期中的初始化.BeginRequest事件.EndRequest事件等. 可以简单理解为HttpApplicat ...

  2. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  3. ABP源码分析七:Setting 以及 Mail

    本文主要说明Setting的实现以及Mail这个功能模块如何使用Setting. 首先区分一下ABP中的Setting和Configuration. Setting一般用于需要通过外部配置文件(或数据 ...

  4. ABP源码分析三十五:ABP中动态WebAPI原理解析

    动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...

  5. MyCat源码分析系列之——前后端验证

    更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...

  6. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  7. YARN DistributedShell源码分析与修改

    YARN DistributedShell源码分析与修改 YARN版本:2.6.0 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述 2 YARN Distrib ...

  8. [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)

    对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...

  9. docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储

    前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...

随机推荐

  1. Azkaban学习之路(二)—— Azkaban 3.x 编译及部署

    一.Azkaban 源码编译 1.1 下载并解压 Azkaban 在3.0版本之后就不提供对应的安装包,需要自己下载源码进行编译. 下载所需版本的源码,Azkaban的源码托管在GitHub上,地址为 ...

  2. spring 5.x 系列第12篇 —— 整合memcached (代码配置方式)

    文章目录 一.说明 1.1 XMemcached客户端说明 1.2 项目结构说明 1.3 依赖说明 二.spring 整合 memcached 2.1 单机配置 2.2 集群配置 2.3 存储基本类型 ...

  3. Apache配置URL重定向

    Apache配置URL重定向 修改/etc/httpd/conf/httpd.conf文件的内容 <Directory "/var/www"> AllowOverrid ...

  4. (H5)canvas实现裁剪图片和马赛克功能,以及又拍云上传图片

    1.核心功能 此组件功能包含: 图片裁剪(裁剪框拖动,裁剪框改变大小): 图片马赛克(绘制马赛克,清除马赛克): 图片预览.图片还原(返回原图.返回处理图): 图片上传(获取签名.上传图片). 2.核 ...

  5. select自定义下拉三角符号,css样式小细节

    本来没有写文章的习惯,但是闲下来了,整理资料,发现还挺纠结,对前端来说.所以整理下,希望对看到的人有所帮助,毕竟我不是前端开发. 起因,是前端告诉我select 框的三角箭头不能自定义.但是第二次的时 ...

  6. 学Redis这篇就够了

    Redis 简介 Redis 优势 Redis 数据类型 string hash list set Zset 小总结 基本命令 发布订阅 简介 实例 发布订阅常用命令 事务 实例 Redis 事务命令 ...

  7. c++学习书籍推荐《C++ Primer Plus中文版(第6版)》下载

    百度云及其他网盘下载地址:点我 编辑推荐 一本经久不衰的C++畅销经典教程:一本支持C++11新标准的程序设计图书.  它被誉为“开发人员学习C++的教程,没有之一”! Amazon网站“Langua ...

  8. 分享几个能用的editplus注册码/2018年序列号

    注册名:host1991 序列号:14F50-CD5C8-E13DA-51100-BAFE6     注册名:360xw    注册码:93A52-85B80-A3308-BF130-40412   ...

  9. 使用kubectl管理k8s集群(二十九)

    前言 在搭建k8s集群之前,我们需要先了解下kubectl的使用,以便在集群部署出现问题时进行检查和处理.命令和语法记不住没有关系,但是请记住主要的语法和命令以及帮助命令的使用. 在下一篇,我们将讲述 ...

  10. 最新 centos7下zabbix 监控redis状态

    准备 先准备两台服务器,已经部署好了zabbix-sever和zabbix-agent zabbix-server 192.168.1.70 centos7.2 zabbix-agent 192.16 ...