.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侧
- 函数导出
[UnmanagedCallersOnly(EntryPoint = "aotsample_add")]
public static int Add(int x, int y)
{
return x + y;
}
调用侧 (.net)
- 先决条件
拷贝 本机AOT 文件,并在构建时输出
- DLLImport
[DllImport("functionlibs1", EntryPoint = "aotsample_add")]
public static extern int aotadd(int x, int y);
坑
- WSL中编译到 Linux-arm64 项目中增加引用
<ItemGroup>
<PackageReference Include="runtime.linux-arm64.Microsoft.DotNet.ILCompiler" Version="8.0.19" />
</ItemGroup>
- System.EntryPointNotFoundException: 'Unable to find an entry point named
函数入口点的 DLL / 函数入口名称错误