C++是如何运行C#/.Net的?

本文探讨了C#语言与C++的关系,指出C++是.Net平台的基础,C#的运行时CLR主要由C++编写。文章通过示例展示了如何使用C++加载并运行C#编译的托管DLL,解释了托管与非托管代码的交互机制,并提到了其他语言如Java和Python的运行模式。
摘要由CSDN通过智能技术生成

前言

C#这门语言是运行在.Net平台上面的。那么.Net平台是依靠什么运行的呢?没错就是C++。严格来说是类C的C++。本篇来看下。

概括

1.引申
知乎上有个提问:C#和C++语句有区别吗?
当时回答的是:
C++严格来说是C#的干爹
那么反过来,C#是C++的干儿子
为什么这么说呢?C#的运行时CLR的小型主机CoreRun超过90%类C的C++。
那么C#的亲爹是谁呢?自然是微软了

2.托管与非托管
实际上大部分.Net程序员都是通过DllImport来导入非托管的C++ API。尤其是Windows上的API,来通过托管代码运行非托管代码。这其实是微软通过CLR虚拟机提供的托管运行非托管的能力。
但是这里有个前提就是,托管要能够运行的起来。如何让托管运行起来呢?一切解决的万事万物,无非就是二进制里面的面向过程的语言C/C++了。这里举几个例子:
一:Java源码通过C++虚拟机JVM来运行的
二:Go的Runtime实现了90%以上的自举,但是它的引导程序依然是C
三:Python,Python作为一种解释性的语言,它解释器里面包含了编译器和虚拟机,它这个虚拟机就是C++.
以上是当今比较流行的几大语言,其实他们的运行模式几乎都是一模一样。编译-》解释-》执行。
这里要说的是.Net依然如此,它是通过C++启动虚拟机进行运行的。

3.代码
一段简单的C#代码:

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

如果要用C++加载这段托管的代码,应该怎么做呢?

下面一段代码就是C加载托管的DLL,运行托管的入门代码HelloWorld

#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";
  //这个呢,就是上面的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;
}

头文件:

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

非常简单的一段程序,轻轻松松通过非托管的C加载调用托管的DLL,把它运行出来。

结尾

作者:江湖评谈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值