前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++是如何运行C#/.Net的?

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

作者头像
江湖评谈
发布2023-08-31 21:19:18
2250
发布2023-08-31 21:19:18
举报
文章被收录于专栏:天下风云天下风云

前言

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#代码:

代码语言:javascript
复制
internal class Program
{
   static void Main(string[] args)
   {
       Console.WriteLine("Hello, World!");
       Console.ReadLine();
   }
}

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

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

代码语言:javascript
复制
#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;
}

头文件:

代码语言:javascript
复制
https://github.com/dotnet/runtime/blob/main/src/native/corehost/hostfxr.h

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

结尾

作者:江湖评谈

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-07-06,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 江湖评谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 概括
  • 结尾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com