跳转至

.net AOT

.net AOT 概述

将应用发布为 本机 AOT 会生成一个 自包含 且已预先编译为本机代码的应用。 本机 AOT 应用具有更快的启动时间和更小的内存占用量。 这些应用可以在未安装 .NET 运行时的计算机上运行。

本地 AOT 的优势在于对于具有大量已部署实例的工作负载(例如云基础设施和超大规模服务)尤其显著。 .NET 8 添加了 对本机 AOT 的 ASP.NET Core 支持。

本机 AOT 部署模型使用预先编译器在发布时将 IL 编译为本机代码。 AOT 原生应用在运行时不使用即时编译器(JIT)。 本地 AOT 应用程序可以在禁止使用 JIT 编译器的受限环境中运行。 本机 AOT 应用程序面向特定的运行时环境,例如 Linux x64 或 Windows x64,就像发布 独立应用一样。

平台 目标架构
Windows x64,ARM64
Linux x64,ARM64
macOS x64,ARM64
iOS ARM64
iOSSim x64,ARM64
tvOS ARM64
tvOSSim x64,ARM64
安卓 x64,ARM64

先决条件

.net 8.0+

环境搭建

Windows 环境准备

  • Visual Studio 2022
  • Visual Studio 2022,包括“使用 C++ 进行桌面开发”的工作负载,以及所有默认组件。

WSL 环境准备

  • WSL Ubuntu 22.04

  • dotnet sdk8

  • 编译链工具

sudo apt-get install clang zlib1g-dev

项目配置

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <InvariantGlobalization>false</InvariantGlobalization>
    <PublishAot>true</PublishAot>
    <SelfContained>true</SelfContained>
    <StripSymbols>false</StripSymbols>
    <IsAotCompatible>true</IsAotCompatible>
  </PropertyGroup>

</Project>

跨平台编译

windows

x64 Windows -> ARM64 Windows

Linux

x64 Linux -> ARM64 Linux

必要的依赖
  • 交叉链接器,或可为目标发出的链接器。 clang 是一个这样的链接器。
  • 目标兼容objcopy或strip,如果为项目启用了StripSymbols。
  • 目标体系结构的 C 运行时的对象文件。
  • 目标体系结构的 zlib 的对象文件。

以下命令可能足以用于 linux-arm64 Ubuntu 22.04 amd64 的编译,尽管 Ubuntu 未记录或保证这一点。

sudo dpkg --add-architecture arm64
sudo bash -c 'cat > /etc/apt/sources.list.d/arm64.list <<EOF
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted universe multiverse
EOF'
sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
sudo sed -i -e 's/deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list
sudo apt update
sudo apt install -y clang llvm binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu zlib1g-dev:arm64

编程

本机AOT侧

  1. 函数导出
    [UnmanagedCallersOnly(EntryPoint = "aotsample_add")]
    public static int Add(int x, int y)
    {
        return x + y;
    }

调用侧 (.net)

  1. 先决条件

拷贝 本机AOT 文件,并在构建时输出

  1. DLLImport
    [DllImport("functionlibs1", EntryPoint = "aotsample_add")]
    public static extern int aotadd(int x, int y);

  1. WSL中编译到 Linux-arm64 项目中增加引用
<ItemGroup>
   <PackageReference Include="runtime.linux-arm64.Microsoft.DotNet.ILCompiler" Version="8.0.19" />
 </ItemGroup>
  1. System.EntryPointNotFoundException: 'Unable to find an entry point named

函数入口点的 DLL / 函数入口名称错误