news 2026/7/8 6:51:03

NET适配HarmonyOS进展

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NET适配HarmonyOS进展

1. 前言

目前国产化系统浪潮下,适配鸿蒙是中国软件大势所趋,.NET作为最适合开发客户端语言之一,适配鸿蒙系统(HarmonyOS Next)是目前.NET开发者最关心的事情。我目前业余时间正在移植Avalonia到HarmonyOS,去年在.NET Conf CN上分享过,目前又取得一点进展,所以本文把所有问题进行整合与大家进行分享。

2. 项目状态

目前.NET可以成功在HarmonyOS Next上运行

Avalonia移植项目在真机上也可以运行,本文主要探讨.NET适配相关工作。

3. 运行时

自HarmonyOS 5.0.0(12)起,禁止匿名内存申请可执行权限,除系统内置的JavaScript引擎外,其他虚拟机不能使用Jit功能,所以无法将CoreCLR接入到鸿蒙系统中,而最新版的Mono虽然支持解释执行,但是由于性能问题也不会接入Mono到鸿蒙系统,最终只能选择接入NativeAOT运行时

4. NativeAOT

支撑鸿蒙可以接入NativeAOT的原理是鸿蒙系统兼容libc是musl的Linux系统的动态库(.so)。而.NET的RID支持linux-musl-arm64/linux-musl-x64,所以理论上可以将.NET程序编译为原生的Linux动态库(.so),然后在鸿蒙的原生项目中,通过dlopen以及dlsym等函数调用C#中的入口函数。

而C#调用鸿蒙api则通过P/Invoke调用鸿蒙的NDK,而ArkUI的TypeScript api则通过NDK中的napi调用。

具体做法可以参考我正在做的Avalonia移植项目: GitHub - OpenHarmony-NET/OpenHarmony.Avalonia · GitHub

5. 已知问题

5.1 syscall限制 (已解决)

鸿蒙系统使用了seccomp限制危险的syscall调用。标准posix下,如果系统不支持某个syscall则返回错误码,而seccomp非常激进,如果调用了非法的sycall则直接杀掉进程。.NET的运行时初始化时,会调用__NR_get_mempolicy系统调用对numa支持进行检查,而这个系统调用不在鸿蒙的seccomp白名单中,所以导致直接宕机。

鸿蒙系统中seccomp的系统调用白名单如下:https://gitee.com/openharmony/startup_init/blob/master/services/modules/seccomp/seccomp_policy/app.seccomp.policy

其实安卓中也有类似的限制,.NET的NativeAOT之所以能在安卓平台下运行是因为.NET中对安卓进行了特殊处理,而在鸿蒙平台我们使用的是Linux平台的代码,所以没有对这些系统调用进行处理。

解决办法则是自行修改代码,将numa的函数全部修改为空函数

5.2 mmap申请虚拟内存过大(已解决)

解决上个问题后,.NET运行时初始化依然不能成功,导致程序崩溃,经过排查发现是GC初始化时会申请256G左右的虚拟内存,导致mmap返回Out Of Memory错误。

解决办法1:设置环境变量“DOTNET_GCHeapHardLimit”,将虚拟内存申请控制在约180G以下即可。

解决办法2:修改源代码,将USE_REGIONS宏关掉。

5.3 ICU,OpenSSL等第三方库缺失(已解决)

解决方案1:从Alpine上偷包 ,因为Alpine的libc是musl,所以理论上Alpine的库在鸿蒙上大部分都能使用。

阿里云Alpine软件包镜像地址:
arm64架构:alpine-edge-main-aarch64安装包下载-开源镜像站-阿里云
amd64架构:alpine-edge-main-x86_64安装包下载-开源镜像站-阿里云

解决方案2:如果该库有cmake项目,则可以通过鸿蒙的CMake工具链编译。

5.4 ICU初始化失败(已解决)

鸿蒙的ICU配置文件路径与默认路径不同,需要调用修改环境变量API,将ICU_DATA修改为/system/usr/ohos_icu
且鸿蒙平台上libICU的大版本是72,要使用这个版本的库。

5.5 NativeAOT如何跨平台编译 (Windows平台已解决)

NativeAOT众所周知不支持跨平台编译,而我的方案需要发布到linux-musl平台,所以无法在Windows上发布,影响开发效率。

解决方案:在项目中引入项目GitHub - OpenHarmony-NET/PublishAotCross: NuGet package to help you cross-compile Native AOT to different OSes/architectures · GitHub

5.6 无法调用Marshal.GetDelegateForFunctionPointer相关函数

Marshal.GetDelegateForFunctionPointer的实现依赖动态生成汇编,而HarmonyOS不支持动态生成汇编代码执行(Jit),使用该函数会导致崩溃。

解决方案: 使用函数指针直接调用。

6. 如何修改NativeAOT代码

前文中提到部分问题的解决方案是修改源码,具体操作步骤如下:
修改完代码,执行以下命令进行编译(linux平台下,需要有编译环境):

./build.sh --subset clr.aot --configuration Release -arch arm64 --cross

编译成功后,打开目录运行时/artifacts/bin/coreclr/linux.arm64.Release/aotsdk,将这里所有的替换到自己电脑nuget的缓存目录, 例如C:\Users\用户名\.nuget\packages\runtime.linux-musl-arm64.microsoft.dotnet.ilcompiler\dotnet版本\sdk

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/8 6:50:14

Windows平台APK安装器技术架构深度解析

Windows平台APK安装器技术架构深度解析 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 在跨平台应用生态快速发展的今天,Windows系统直接运行Android应用的…

作者头像 李华
网站建设 2026/7/8 6:49:52

Transformer 入门:一个「快递分拣员」的自白

1. 引言 想象一下,你是一家大型快递公司的分拣中心主管。每天有成千上万的包裹(词语)涌进来,你需要让每个包裹知道它该去哪、和谁一起走、在整个流程中扮演什么角色。这就是 Transformer 在做的事——只不过它分拣的不是包裹&…

作者头像 李华
网站建设 2026/7/8 6:49:13

深耕工业照明匠心之选,靠谱机床照明灯厂家推荐

纵观当下制造行业,设备不断迭代、工艺持续升级,行业竞争愈发白热化。很多制造企业聚焦机床精度、加工工艺、产能管控,却常常忽略机床照明这一基础配套。殊不知一盏合格的机床灯,不仅是工位照明工具,更是保障加工精度、…

作者头像 李华
网站建设 2026/7/8 6:48:56

gwasglue:基因组数据分析的智能翻译官,让GWAS数据无缝对话

gwasglue:基因组数据分析的智能翻译官,让GWAS数据无缝对话 【免费下载链接】gwasglue Linking GWAS data to analytical tools in R 项目地址: https://gitcode.com/gh_mirrors/gw/gwasglue 在基因组学研究的广阔天地中,研究人员常常面…

作者头像 李华
网站建设 2026/7/8 6:48:14

出差买特产,竟然能当天打包发货?

出差买特产,竟然能当天打包发货?在快节奏的现代生活中,出差已经成为许多人的常态。而每次出差归来,总想带点当地特色产品给家人或朋友,以表达心意。然而,传统的购买方式往往需要现场挑选、排队结账&#xf…

作者头像 李华
网站建设 2026/7/8 6:47:40

从零构建系统管理员智能助理:技术架构与工程实践

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 在实际项目开发中,系统管理员和主操作系统的角色设计往往决定了整个系统的可维护性和用户体验。特别是当系统需要与用户进…

作者头像 李华