.NET 7 SDK、Desktop development with C++ workload。
IDEVisual Studio 2022Desktop development with C workload是一个工具集里面包含 C 开发工具需要在Visual Studio Installer中安装如下图红框中所示。创建一个控制台项目首先创建一个 .NET 7 控制台项目名称为CsharpAot。打开项目之后基本代码如图所示我们使用下面的代码做测试public class Program { static void Main() { Console.WriteLine(C# Aot!); Console.ReadKey(); } }体验 AOT 编译这一步可以参考官方网站的更多说明https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/为了能够让项目发布时使用 AOT 模式需要在项目文件中加上PublishAottrue/PublishAot选项。然后使用 Visual Studio 发布项目。发布项目的配置文件设置需要按照下图进行配置。AOT 跟生成单个文件两个选项不能同时使用因为 AOT 本身就是单个文件。配置完成后点击发布然后打开Release目录会看到如图所示的文件。.exe是独立的可执行文件不需要再依赖.NET Runtime环境这个程序可以放到其他没有安装 .NET 环境的机器中运行。然后删除以下三个文件CsharpAot.exp CsharpAot.lib CsharpAot.pdb光用.exe即可运行其他是调试符号等文件不是必需的。剩下CsharpAot.exe文件后启动这个程序C# 调用库函数这一部分的代码示例是从笔者的一个开源项目中抽取出来的这个项目封装了一些获取系统资源的接口以及快速接入 Prometheus 监控。不过很久没有更新了最近没啥动力更新读者可以点击这里了解一下这个项目https://github.com/whuanle/CZGL.SystemInfo/tree/net6.0/src/CZGL.SystemInfo/Memory因为后续代码需要所以现在请开启 “允许不安全代码”。本小节的示例是通过使用kernel32.dll去调用 Windows 的内核 API(Win32 API)调用GlobalMemoryStatusEx函数检索有关系统当前使用物理内存和虚拟内存的信息。使用到的 Win32 函数可参考https://learn.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/nf-sysinfoapi-globalmemorystatusex关于 .NET 调用动态链接库的方式在 .NET 7 之前通过这样调用[DllImport(Kernel32.dll, CharSet CharSet.Auto, SetLastError true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern Boolean GlobalMemoryStatusEx(ref MemoryStatusExE lpBuffer);在 .NET 7 中出现了新的操作方式[LibraryImport]。文档是这样介绍的Indicates that a source generator should create a function for marshalling arguments instead of relying on the runtime to generate an equivalent marshalling function at run time. 指示源生成器应创建用于编组参数的函数而不是依赖运行库在运行时生成等效的编组函数。简单来说就是我们要使用 AOT 写代码然后代码中引用到别的动态链接库时需要使用[LibraryImport]引入这些函数。笔者没有在 AOT 下测试过[DllImport]读者感兴趣可以试试。新建两个结构体MEMORYSTATUS.cs、MemoryStatusExE.cs。MEMORYSTATUS.cspublic struct MEMORYSTATUS { internal UInt32 dwLength; internal UInt32 dwMemoryLoad; internal UInt32 dwTotalPhys; internal UInt32 dwAvailPhys; internal UInt32 dwTotalPageFile; internal UInt32 dwAvailPageFile; internal UInt32 dwTotalVirtual; internal UInt32 dwAvailVirtual; }MemoryStatusExE.cspublic struct MemoryStatusExE { /// summary /// 结构的大小以字节为单位必须在调用 GlobalMemoryStatusEx 之前设置此成员可以用 Init 方法提前处理 /// /summary /// remarks应当使用本对象提供的 Init 而不是使用构造函数/remarks internal UInt32 dwLength; /// summary /// 一个介于 0 和 100 之间的数字用于指定正在使用的物理内存的大致百分比0 表示没有内存使用100 表示内存已满。 /// /summary internal UInt32 dwMemoryLoad; /// summary /// 实际物理内存量以字节为单位 /// /summary internal UInt64 ullTotalPhys; /// summary /// 当前可用的物理内存量以字节为单位。这是可以立即重用而无需先将其内容写入磁盘的物理内存量。它是备用列表、空闲列表和零列表的大小之和 /// /summary internal UInt64 ullAvailPhys; /// summary /// 系统或当前进程的当前已提交内存限制以字节为单位以较小者为准。要获得系统范围的承诺内存限制请调用GetPerformanceInfo /// /summary internal UInt64 ullTotalPageFile; /// summary /// 当前进程可以提交的最大内存量以字节为单位。该值等于或小于系统范围的可用提交值。要计算整个系统的可承诺值调用GetPerformanceInfo核减价值CommitTotal从价值CommitLimit /// /summary internal UInt64 ullAvailPageFile; /// summary /// 调用进程的虚拟地址空间的用户模式部分的大小以字节为单位。该值取决于进程类型、处理器类型和操作系统的配置。例如对于 x86 处理器上的大多数 32 位进程此值约为 2 GB对于在启用4 GB 调整的系统上运行的具有大地址感知能力的 32 位进程约为 3 GB 。 /// /summary internal UInt64 ullTotalVirtual; /// summary /// 当前在调用进程的虚拟地址空间的用户模式部分中未保留和未提交的内存量以字节为单位 /// /summary internal UInt64 ullAvailVirtual; /// summary /// 预订的。该值始终为 0 /// /summary internal UInt64 ullAvailExtendedVirtual; internal void Refresh() { dwLength checked((UInt32)Marshal.SizeOf(typeof(MemoryStatusExE))); } }定义引用库函数的入口public static partial class Native { /// summary /// 检索有关系统当前使用物理和虚拟内存的信息 /// /summary /// param namelpBuffer/param /// returns/returns [LibraryImport(Kernel32.dll, SetLastError true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial Boolean GlobalMemoryStatusEx(ref MemoryStatusExE lpBuffer); }然后调用Kernel32.dll中的函数public class Program { static void Main() { var result GetValue(); Console.WriteLine($当前实际可用内存量{result.ullAvailPhys / 1000 / 1000}MB); Console.ReadKey(); } /// exception crefWin32Exception/exception public static MemoryStatusExE GetValue() { var memoryStatusEx new MemoryStatusExE(); // 重新初始化结构的大小 memoryStatusEx.Refresh(); // 刷新值 if (!Native.GlobalMemoryStatusEx(ref memoryStatusEx)) throw new Win32Exception(无法获得内存信息); return memoryStatusEx; } }使用 AOT 发布项目执行CsharpAot.exe文件。减少体积在前面两个例子中可以看到CsharpAot.exe文件大约在 3MB 左右但是这个文件还是太大了那么我们如何进一步减少 AOT 文件的大小呢读者可以从这里了解如何裁剪程序https://learn.microsoft.com/zh-cn/dotnet/core/deploying/trimming/trim-self-contained需要注意的是裁剪是没有那么简单的里面配置繁多有一些选项不能同时使用每个选项又能带来什么样的效果这些选项可能会让开发者用得很迷茫。经过笔者的大量测试笔者选用了以下一些配置能够达到很好的裁剪效果供读者测试。首先引入一个库ItemGroup PackageReference IncludeMicrosoft.DotNet.ILCompiler Version7.0.0-* / /ItemGroup接着在项目文件中加入以下选项!--AOT 相关-- PublishAottrue/PublishAot TrimModefull/TrimMode RunAOTCompilationTrue/RunAOTCompilation PublishTrimmedtrue/PublishTrimmed TrimmerRemoveSymbolstrue/TrimmerRemoveSymbols PublishReadyToRunEmitSymbolsfalse/PublishReadyToRunEmitSymbols DebuggerSupportfalse/DebuggerSupport EnableUnsafeUTF7Encodingtrue/EnableUnsafeUTF7Encoding InvariantGlobalizationtrue/InvariantGlobalization HttpActivityPropagationSupportfalse/HttpActivityPropagationSupport MetadataUpdaterSupporttrue/MetadataUpdaterSupport UseSystemResourceKeystrue/UseSystemResourceKeys IlcDisableReflection true/IlcDisableReflection最后发布项目。吃惊生成的可执行文件只有 1MB 了而且还可以正常执行。笔者注虽然现在看起来 AOT 的文件很小了但是如果使用到HttpClient、System.Text.Json等库哪怕只用到了一两个函数最终包含这些库以及这些库使用到的依赖生成的 AOT 文件会大得惊人。所以如果项目中使用到其他 nuget 包的时候别想着生成的 AOT 能小多少C# 导出函数这一步可以从时总的博客中学习更多跨语言调用C#代码的新方式-DllExport - InCerry - 博客园PS时总真的太强了。在 C 语言中导出一个函数的格式可以这样// MyCFuncs.h #ifdef __cplusplus extern C { // only need to export C interface if // used by C source code #endif __declspec( dllimport ) void MyCFunc(); __declspec( dllimport ) void AnotherCFunc(); #ifdef __cplusplus } #endif当代码编译之后我们就可以通过引用生成的库文件调用MyCFunc、AnotherCFunc两个方法。如果不导出的话别的程序是无法调用库文件里面的函数。因为 .NET 7 的 AOT 做了很多改进因此.NET 程序也可以导出函数了。新建一个项目名字就叫CsharpExport吧我们接下来就在这里项目中编写我们的动态链接库。添加一个CsharpExport.cs文件内容如下using System.Runtime.InteropServices; namespace CsharpExport { public class Export { [UnmanagedCallersOnly(EntryPoint Add)] public static int Add(int a, int b) { return a b; } } }然后在.csproj文件中加上PublishAot选项。然后通过以下命令发布项目生成链接库dotnet publish -p:NativeLibShared -r win-x64 -c Release看起来还是比较大为了继续裁剪体积我们可以在CsharpExport.csproj中加入以下配置以便生成更小的可执行文件。!--AOT 相关-- PublishAottrue/PublishAot TrimModefull/TrimMode RunAOTCompilationTrue/RunAOTCompilation PublishTrimmedtrue/PublishTrimmed TrimmerRemoveSymbolstrue/TrimmerRemoveSymbols PublishReadyToRunEmitSymbolsfalse/PublishReadyToRunEmitSymbols DebuggerSupportfalse/DebuggerSupport EnableUnsafeUTF7Encodingtrue/EnableUnsafeUTF7Encoding InvariantGlobalizationtrue/InvariantGlobalization HttpActivityPropagationSupportfalse/HttpActivityPropagationSupport MetadataUpdaterSupporttrue/MetadataUpdaterSupport UseSystemResourceKeystrue/UseSystemResourceKeys IlcDisableReflection true/IlcDisableReflectionC# 调用 C# 生成的 AOT在本小节中将使用CsharpAot项目调用CsharpExport生成的动态链接库。把CsharpExport.dll复制到CsharpAot项目中并配置始终复制。在CsharpAot的Native中加上[LibraryImport(CsharpExport.dll, SetLastError true)] [return: MarshalAs(UnmanagedType.I4)] internal static partial Int32 Add(Int32 a, Int32 b);然后在代码中使用static void Main() { var result Native.Add(1, 2); Console.WriteLine($1 2 {result}); Console.ReadKey(); }在 Visual Studio 里启动 Debug 调试可以看到是正常运行的。接着将CsharpAot项目发布为 AOT 后再次执行可以看到.NET AOT 调用 .NET AOT 的代码是没有问题的。Golang 部分Go 生成 Windows 动态链接库需要安装 GCC通过 GCC 编译代码生成对应平台的文件。安装 GCC需要安装 GCC 10.3如果 GCC 版本太新会导致编译 Go 代码失败。打开 tdm-gcc 官网通过此工具安装 GCC官网地址Download | tdm-gcc

相关新闻

联想拯救者独显报 43 花屏黑屏维修|20 年曾工芯片重植低温锡通病修复

联想拯救者独显报 43 花屏黑屏维修|20 年曾工芯片重植低温锡通病修复

不少联想拯救者 Y7000P/Y9000P/R9000P 玩家都遇到同款故障:设备管理器独显带黄色感叹号,提示代码 43,重装驱动、重装系统很难解决问题,伴随花屏、条纹、黑屏、游戏掉帧、独显无法正常工作等情况。电脑长期高负载游戏、冷热交替&am…

2026/7/2 5:48:53阅读更多 →
轮式双臂机器人在VLA大模型时代的科研价值与产业应用

轮式双臂机器人在VLA大模型时代的科研价值与产业应用

摘要轮式双臂机器人通过”移动底盘仿生双臂”复合架构,在具身智能、柔性制造与科研教育领域展现显著成本效益与场景适应性。2026年中国轮式双臂机器人市场规模预计突破18亿元,增速达350%。本文梳理技术架构与应用场景,以时空行者行者R1为典型…

2026/7/2 5:48:53阅读更多 →
【EI会议】智能交通系统与自动化控制方向

【EI会议】智能交通系统与自动化控制方向

2026智能交通系统与自动化控制国际会议(ITSAC 2026) 时间:2026年7月4-5日 地点:河南省-洛阳市 论文出版:SPIE 论文收录:EI Compendex、Scopus 会议主题:智能交通系统;交通建模与仿真…

2026/7/2 5:43:53阅读更多 →
Spring Boot多模块工程最佳实践(企业级落地手册·2024版)

Spring Boot多模块工程最佳实践(企业级落地手册·2024版)

更多请点击: https://kaifayun.com 第一章:Spring Boot多模块工程全景认知与演进趋势 Spring Boot多模块工程已从早期的“单体分包”实践,逐步演进为支撑云原生、微服务治理与领域驱动设计(DDD)落地的核心架构范式。其…

2026/7/2 6:59:00阅读更多 →
IDEA中Git Stash总丢失代码?3个致命配置陷阱与4步零误差恢复实战指南

IDEA中Git Stash总丢失代码?3个致命配置陷阱与4步零误差恢复实战指南

更多请点击: https://intelliparadigm.com 第一章:IDEA中Git Stash总丢失代码?3个致命配置陷阱与4步零误差恢复实战指南 IntelliJ IDEA 的 Git Stash 功能看似便捷,却常因隐性配置冲突导致 stash 记录静默消失、切换分支后 stash…

2026/7/2 6:59:00阅读更多 →
Figma到Unity转换工具:如何5分钟内将设计原型变为可运行UI

Figma到Unity转换工具:如何5分钟内将设计原型变为可运行UI

Figma到Unity转换工具:如何5分钟内将设计原型变为可运行UI 【免费下载链接】FigmaToUnityImporter The project that imports nodes from Figma into unity. 项目地址: https://gitcode.com/gh_mirrors/fi/FigmaToUnityImporter 当我们面对游戏开发中设计到实…

2026/7/2 6:59:00阅读更多 →
必火AI做GEO内容时应该坚持哪些合规边界

必火AI做GEO内容时应该坚持哪些合规边界

课程和工具类品牌做GEO内容,更应该重视合规边界。短期声量不应建立在夸大承诺和虚构案例上。 不承诺不可控结果 这个问题的关键,是把营销表达回到真实业务。企业要围绕用户真实会问的问题组织内容,而不是只重复品牌口号。内容越具体、越克制…

2026/7/2 6:59:00阅读更多 →
【计算机科学与应用】基于Mask R-CNN的近海漂浮垃圾智能识别与清理路径规划系统

【计算机科学与应用】基于Mask R-CNN的近海漂浮垃圾智能识别与清理路径规划系统

导读: 针对近海漂浮垃圾人工清理效率低、成本高和风险大的问题,本文设计了一套基于Mask R-CNN的智能检测与清理路径规划系统。系统采用Roboflow海洋垃圾数据集,包含11类目标、10,000张图像和56,272个标注实例;基于ResNet-50-FPN的…

2026/7/2 6:59:00阅读更多 →
AI工具2026:专业Figma插件与网页端UI设计测评

AI工具2026:专业Figma插件与网页端UI设计测评

说实话,做设计这行十几年了,我见过太多号称能“颠覆行业”的工具,最后大多雷声大雨点小。但2026年这波AI原型工具,确实让我感觉不一样了。它们不再是那种只能改改文案、换换图片的“伪AI”,而是真的能理解你的设计意图…

2026/7/2 6:54:00阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/1 4:42:14阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/1 5:19:01阅读更多 →
塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧 【免费下载链接】BOTW-Save-Editor-GUI A Work in Progress Save Editor for BOTW 项目地址: https://gitcode.com/gh_mirrors/bo/BOTW-Save-Editor-GUI 想在《塞尔达传说:旷野之息…

2026/7/2 0:03:01阅读更多 →
告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

在本地开发环境使用云厂商 CLI 时,传统的 AccessKey(AK)方式需要手动创建、下载和保管密钥,不仅繁琐,还存在泄漏风险。其实,主流云平台都已提供基于 OAuth 2.0 的免密认证方案,让开发者可以通过浏览器登录一次性完成授权,CLI 自动管理临时凭证的刷新,兼顾了便利与安全…

2026/7/2 0:03:01阅读更多 →
基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

1. 项目背景与核心价值在嵌入式系统开发领域,高精度定位与导航一直是极具挑战性的技术方向。传统方案往往面临成本、精度和实时性难以兼顾的困境。这个项目通过13DOF(13自由度)传感器组合与PIC32MZ2048EFH100高性能MCU的协同工作,…

2026/7/2 0:03:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/2 0:33:58阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/2 1:32:11阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/2 1:50:13阅读更多 →