前言:

曾几何时,一直想自己定制一个CLR运行时玩玩。满足下技术控的虚荣心,本篇带你一步一步打造一个属于自己的.Net 7运行时。

概括

假设你的电脑已经安装了.Net,并且运行正常。在进行自定义运行时之前,首先需要准备三样东西。

其一:

找到你当前安装的.Net宿主目录,一般的默认目录都是:

C:\Program Files\dotnet\host\fxr

在这个目录下面是你的当前电脑安装的.Net 版本了。比如7.0.0或者其它版本,它是一个文件夹,它的路径看起来是这样:

C:\Program Files\dotnet\host\fxr\7.0.0

这个路径下面有一个hostfxr.dll文件,记住它,后面要用。

其二:

我们进入到这个网址:

https://github.com/dotnet/runtime/blob/main/src/native/corehost/hostfxr.h

可以看到这个github路径下,是一个hostfxr.h的标准C头文件。你把它里面的内容复制到记事本,然后保存文件名为:hostfxr.h。后面要用。

其三:

准备一个.Net 控制台应用程序,代码就是一个Helloworld输出,如下:

    internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.ReadLine();
}
}

把它编译之后,找到它的路径。

.Net 7的运行时里面有个规定。路径分为,主机路径Host_path也就是你需要运行程序的Debug路径,比如本例的

Host_Path=E:\Visual Studio Project\Test\Test\bin\Debug\net6.0

APP路径,也就是的程序编译之后的DLL路径,本例如下:

ConsoleApp=\Visual Studio Project\Test\Test\bin\Debug\net6.0\Test.dll

.Net根目录路径:

DotNet_Root=C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.8

OK,假如你以上三样准备好了,我们继续下面的步骤。

定制

用Visual Studio新建一个C++控制台应用程序,取名:SuZhu。新建之后,会跳出一个SuZhu.cpp文件。把里面的代码全部删掉。用下面的代码替代:

#include <stdio.h>
#include <Windows.h>
#include "hostfxr.h" hostfxr_main_startupinfo_fn startupinfo_fptr;// 实例化一个运行时入口函数指针,此指针用以调用了.Net 托管代码里面的Main函数入口 int main(int argc, char** argv)
{
// 这个就是上面的Host_Path路径。注意CPP里面的路径是双斜杠
const wchar_t* Host_Path = L"E:\\Visual Studio Project\\Test\\Test\\bin\\Debug\\net6.0";
//这个就是上面的ConsoleApp
const wchar_t* ConsoleApp = L"E:\\Visual Studio Project\\Test\\Test\\bin\\Debug\\net6.0\\Test.dll";//这个是上面的AppConsole路径。
//这个呢,就是上面的DotNet_Root路径。
const wchar_t* DotNet_Root = L"C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\7.0.0";
//这里的argvV参数区别于Main的argv参数,主要用于运行时入口函数指针的参数。
const wchar_t* argvV = L"";
//用LoadLibraryExA加载上面前期准备的步骤里的hostfxr.dll
HMODULE h = LoadLibraryExA("C:\\Program Files\\dotnet\\host\\fxr\\7.0.0\\hostfxr.dll", NULL, 0);
//通过GetProcAddress函数获取到运行时入口函数指针,也就是上面实例化的startupinfo_fptr变量
startupinfo_fptr = (hostfxr_main_startupinfo_fn)GetProcAddress(h, "hostfxr_main_startupinfo");
//通过传入运行时入口函数指针的参数,包括Host_Path,DotNet_Root,ConsoleApp等参数。来运行CLR,用以调用ConsoleApp里面的Main函数入口。
startupinfo_fptr(1, &argvV, Host_Path, DotNet_Root, ConsoleApp); return 0;
}

然后引入上面步骤二里面保存记事本的文件hostfxr.h。

点击项目展开-》头文件-》右键添加--》现有项目,选择hostfxr.h。

如果你以上步骤都实现了,并且没有问题。那么现在请摁Visual Sutdio的F5按钮运行当前CPP程序。

结果就会打印出Hello, World!

如下图所示:

结尾:

这个是一个非常小型且精简的CLR运行时程序。屏蔽了繁琐的实现过程。你可以通过这个小型的CLR运行时,构建自己的定制型的运行时。比如这个Host_Path,ConsoleApp传参方式等等。本篇只是最基础的展示。

以上是C++和C#混搞,对于部分.Net程序员可能有点难度。

如果有有不明白的,可以扫码私信我。

.Net 7 高端玩法,自定义一个CLR运行时的更多相关文章

  1. AB实验的高端玩法系列3 - AB组不随机?观测试验?Propensity Score

    背景 都说随机是AB实验的核心,为什么随机这么重要呢?有人说因为随机所以AB组整体不存在差异,这样才能准确估计实验效果(ATE) \[ ATE = E(Y_t(1) - Y_c(0)) \] 那究竟随 ...

  2. AB实验的高端玩法系列4- 实验渗透低?用户未被触达?CACE/LATE

    CACE全称Compiler Average Casual Effect或者Local Average Treatment Effect.在观测数据中的应用需要和Instrument Variable ...

  3. 第四模块MySQL50题作业,以及由作业引申出来的一些高端玩法

    一.表关系 先参照如下表结构创建7张表格,并创建相关约束                 班级表:class       学生表:student       cid caption grade_id ...

  4. AB实验的高端玩法系列2 - 更敏感的AB实验, CUPED!

    背景 AB实验可谓是互联网公司进行产品迭代增加用户粘性的大杀器.但人们对AB实验的应用往往只停留在开实验算P值,然后let it go...let it go ... 让我们把AB实验的结果简单的拆解 ...

  5. 高端面试必备:一个Java对象占用多大内存

    这个问题一般会出现在稍微高端一点的 Java 面试环节.要求面试者不仅对 Java 基础知识熟悉,更重要的是要了解内存模型. Java 对象模型 HotSpot JVM 使用名为 oops (Ordi ...

  6. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  7. Linux内存描述之高端内存--Linux内存管理(五)

    1. 内核空间和用户空间 过去,CPU的地址总线只有32位, 32的地址总线无论是从逻辑上还是从物理上都只能描述4G的地址空间(232=4Gbit),在物理上理论上最多拥有4G内存(除了IO地址空间, ...

  8. Linux高端内存映射(上)【转】

    转自:http://blog.csdn.net/vanbreaker/article/details/7579941 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 高端内 ...

  9. Linux内存描述之高端内存–Linux内存管理(五)

    服务器体系与共享存储器架构 日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDriver ...

  10. 全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等

    本文来自腾讯QQ技术团队工程师许灵锋.周海发的技术分享. 一.引言 自 2015 年春节以来,QQ 春节红包经历了企业红包(2015 年).刷一刷红包(2016 年)和 AR 红包(2017 年)几个 ...

随机推荐

  1. 使用VsCode调试UE5的PuerTs

    使用VsCode调试UE5的PuerTs 1.下载测试的Demo项目 配置PuerTs的步骤这里不赘述. 2.准备工作 2.1 打开项目 正常来说,直接打开项目可以看到如下画面 如果直接点击运行,可以 ...

  2. jmeter接口自动化-通过csv文件读取用例并执行测试

    最近在公司测试中经常使用jmeter这个工具进行接口自动化,简单记录下~ 一.在csv文件中编写好用例 首先在csv文件首行填写相关参数(可根据具体情况而定)并编写测试用例.脚本可通过优先级参数控制执 ...

  3. python(27)反射机制

    1. 什么是反射? 它的核心本质其实就是基于字符串的事件驱动,通过字符串的形式去操作对象的属性或者方法 2. 反射的优点 一个概念被提出来,就是要明白它的优点有哪些,这样我们才能知道为什么要使用反射. ...

  4. RabbitMq消息手动应答、放回队列重新消费、设置队列消息持久化、分发模式

    RabbitMq消息手动应答,放回队列重新消费,设置队列消息持久化 消息应答 概念 消费者完成一个任务可能需要一段时间,如果其中一个消费者处理一个长的任务并仅只完成了部分突然它挂掉了,会发生什么情况. ...

  5. Huawei OJ 题解 - 1. A + B Problem - Go 参考解答

    # Huawei OJ 题解 - 1. A + B Problem - Go 参考解答## 简介- 详情:http://oj.rnd.huawei.com/problems/1/details- 难度 ...

  6. 【云原生 · Kubernetes】apiserver高可用

    个人名片: 因为云计算成为了监控工程师‍ 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying 7.1 高可用选型 ipvs+keepalived nginx+keepalived hap ...

  7. ArcObjects SDK开发 007 自定义App-Command-Tool框架

    1.为什么再设计一套App-Command-Tool框架 为什么我们要自己再设计一套App-Command框架,而不直接使用AO API中的AxControl-ICommand这套已经非常好的框架呢? ...

  8. day25 前端

    https://www.dcloud.io/hbuilderx.html 下载HbuilderX,直接解压缩双击打开 html5 <!DOCTYPE html><!-- 文档类型,声 ...

  9. 【Java SE】Day01 前言、入门程序、常量、变量

    回顾一下Java之前学的内容 Day01 前言.入门程序.常量.变量 一.基础知识 莱布尼茨发明二进制,辗转相除与8421位权法互转,1B=1bit=1字节=8位=8byte dos cls清屏dir ...

  10. 【Java SE进阶】Day04 Map、Debug

    一.Map集合 1.概述 映射 /双列集合 集合分为Collection(存储一个元素 )和Map(存储一对元素) 键不能重复,值可以重复 2.常用子类 HashMap 哈希表存储数据 元素存取数据不 ...