项目状态目前.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调用。危险的syscall调用。标准posix下如果系统不支持某个syscall则返回错误码而seccomp非常激进如果调用了非法的sycall则直接杀掉进程。.NET的运行时初始化时会调用__NR_get_mempolicy系统调用对numa支持进行检查而这个系统调用不在鸿蒙的seccomp白名单中所以导致直接宕机。鸿蒙.NET的NativeAOT之所以能在安卓平台下运行是因为.NET中对安卓进行了特殊处理而在鸿蒙平台我们使用的是Linux平台的代码所以没有对这些系统调用进行处理。解决办法则是自行修改代码将numa的函数全部修改为空函数5.2 mmap申请虚拟内存过大已解决解决上个问题后.NET运行时初始化依然不能成功导致程序崩溃经过排查发现是GC初始化时会申请256G左右的虚拟内存导致mmap返回Out Of Memory错误。解决办法1设置环境变量“DOTNET_GCHeapHardLimit”将虚拟内存申请控制在约180G以下即可。解决办法2修改源代码将USE_REGIONS宏关掉。5.3 ICUOpenSSL等第三方库缺失已解决解决方案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上发布影响开发效率。解决方案在项目中引入项目https://github.com/OpenHarmony-NET/PublishAotCross5.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版本\sdk7.相关链接
适配HarmonyOS进展
发布时间:2026/7/2 6:08:07
项目状态目前.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调用。危险的syscall调用。标准posix下如果系统不支持某个syscall则返回错误码而seccomp非常激进如果调用了非法的sycall则直接杀掉进程。.NET的运行时初始化时会调用__NR_get_mempolicy系统调用对numa支持进行检查而这个系统调用不在鸿蒙的seccomp白名单中所以导致直接宕机。鸿蒙.NET的NativeAOT之所以能在安卓平台下运行是因为.NET中对安卓进行了特殊处理而在鸿蒙平台我们使用的是Linux平台的代码所以没有对这些系统调用进行处理。解决办法则是自行修改代码将numa的函数全部修改为空函数5.2 mmap申请虚拟内存过大已解决解决上个问题后.NET运行时初始化依然不能成功导致程序崩溃经过排查发现是GC初始化时会申请256G左右的虚拟内存导致mmap返回Out Of Memory错误。解决办法1设置环境变量“DOTNET_GCHeapHardLimit”将虚拟内存申请控制在约180G以下即可。解决办法2修改源代码将USE_REGIONS宏关掉。5.3 ICUOpenSSL等第三方库缺失已解决解决方案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上发布影响开发效率。解决方案在项目中引入项目https://github.com/OpenHarmony-NET/PublishAotCross5.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版本\sdk7.相关链接