1. 前言

目前国产化系统浪潮下,适配鸿蒙是中国软件大势所趋,.NET作为最适合开发客户端语言之一,适配鸿蒙系统(HarmonyOS Next)是目前.NET开发者最关心的事情。我目前业余时间正在移植Avalonia到HarmonyOS,去年在.NET Config 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移植项目: https://github.com/CeSun/OpenHarmony.Avalonia

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架构:https://mirrors.aliyun.com/alpine/edge/main/aarch64/

amd64架构:https://mirrors.aliyun.com/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/CeSun/PublishAotCross

6. 如何修改NativeAOT代码

前文中提到部分问题的解决方案是修改源码,具体操作步骤如下:

修改完代码,执行以下命令进行编译(linux平台下,需要有编译环境):

./build.sh --subset mono+libs --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

7.相关链接

https://github.com/dotnet/runtime/issues/110074

https://github.com/dotnet/runtime/issues/111649

.NET适配HarmonyOS进展的更多相关文章

  1. 手把手教你玩转HarmonyOS版地图应用开发

    ​一.导读 7月31日,华为HarmonyOS开发者日将在杭州举行.为了方便更多开发者,高德开放平台地图SDK已在业内率先实现鸿蒙化迁移和重构,全面适配HarmonyOS并面向开发者免费发布.开发者可 ...

  2. 360携手HarmonyOS打造独特的“天气大师”

    做创新,首先要找到有增长趋势的流量红利,对我们来说,HarmonyOS就是绝佳的合作伙伴. --申悦 360手机助手创研产品部负责人 一.我们是谁? 我们来自360,是一支致力于孵化新业务的内部创新小 ...

  3. 开源基于docker的任务调度器pipeline,比`quartzs` 更强大的分布式任务调度器

    pipeline 分布式任务调度器 目标: 基于docker的布式任务调度器, 比quartzs,xxl-job 更强大的分布式任务调度器. 可以将要执行的任务打包为docker镜像,或者选择已有镜像 ...

  4. HarmonyOS开发者看过来,HDD上海站传递的重要信息都在这里

    4月17日,颇有HarmonyOS年度总结性质的HarmonyOS开发者日活动上海站正式开始. 活动中,华为消费者业务AI与智慧全场景业务部副总裁段孟对HarmonyOS生态建设的最新进展做了发言,并 ...

  5. 最全华为鸿蒙 HarmonyOS 开发资料汇总

    开发 本示例基于 OpenHarmony 下的 JavaScript UI 框架,进行项目目录解读,JS FA.常用和自定义组件.用户交互.JS 动画的实现,通过本示例可以基本了解和学习到 JavaS ...

  6. 让那些为Webkit优化的网站也能适配IE10

    特别声明:此篇文章由David根据Charles Morris的英文文章原名<Adapting your WebKit-optimized site for Internet Explorer ...

  7. 让那些为Webkit优化的网站也能适配IE10(转载)

    转载地址:http://www.w3cplus.com/css3/adapting-your-webkit-optimized-site-for-internet-explorer-10.html 特 ...

  8. PowerBuilder编程新思维3:适配(三层架构与GraphQL)

    PowerBuilder编程新思维3:适配(三层架构与GraphQL) PB在富客户端时代,是一线开发工具.随着网络发展,主流架构演进到三层架构的时代,PB拿不出有力的三层架构,已经明显力不从心,市场 ...

  9. 华为 鸿蒙系统(HarmonyOS)

    HarmonyOS Ⅰ. 鸿蒙系统简介 鸿蒙系统(HarmonyOS),是第一款基于微内核的全场景分布式OS,是华为自主研发的操作系统.2019年8月9日,鸿蒙系统在华为开发者大会<HDC.20 ...

  10. 鸿蒙HarmonyOS应用开发落地实践,Harmony Go 技术沙龙落地北京

    12月26日,华为消费者BG软件部开源中心与51CTO Harmony OS技术社区携手,共同主办了主题为"Harmony OS 应用开发落地实践"的 Harmony Go 技术沙 ...

随机推荐

  1. Nuxt.js 应用中的 webpack:progress 事件钩子

    title: Nuxt.js 应用中的 webpack:progress 事件钩子 date: 2024/11/27 updated: 2024/11/27 author: cmdragon exce ...

  2. Mybatis【12】-- Mybatis多条件怎么查询?

    很多时候,我们需要传入多个参数给sql语句接收,但是如果这些参数整体不是一个对象,那么我们应该怎么做呢?这里有两种解决方案,仅供参考. 1.将多个参数封装成为Map 测试接口,我们传入一个Map,里面 ...

  3. 技术漫谈|IVR通用开发框架简说

    IVR为Interactive Voice Response的缩写,意为交互式语音应答(系统).它可以应答客户的呼叫,然后为呼叫者提供语音导航或自助服务,呼叫者可通过按键输入或使用语音命令进行选择.随 ...

  4. idea 2023.1.2 破解/激活

    参考:(感谢作者提供的破解教程,谢谢) IntelliJ IDEA 2023.1.1最新激活破解教程(永久激活,亲测有效) - 异常教程 (exception.site) 下载idea : 链接:ht ...

  5. 查看MySQL数据库所有的表名、表注释、字段名称、类型、长度、备注,一键导出生成数据库字典

    一.先了解下INFORMATION_SCHEMA1.在MySQL中,把INFORMATION_SCHEMA看作是一个数据库,确切说是信息数据库.其中保存着关于MySQL服务器所维护的所有其他数据库的信 ...

  6. Qt/C++编写视频监控系统81-Onvif报警抓图和录像并回放

    一.前言 视频监控系统中的图文警情模块,是通过Onvif协议的事件订阅拿到的,通过事件订阅后,设备的各种报警事件比如入侵报警/遮挡报警/越界报警/开关量报警等,触发后都会主动往订阅者发送,而且一般都是 ...

  7. Qt/C++编写网络摄像头推流(4路1080P主码流只占用0.2%CPU/极低延时极速响应)

    一.前言说明 将从网络摄像头拉流过来的视频流重新推流出去,是目前一个很常规的做法,尤其是推流到流媒体服务中心,这样流媒体服务中心就把散落在各个区域的监控摄像头集中起来统一管理,同时提供对外一致的访问接 ...

  8. Qt编写物联网管理平台39-报警联动

    一.前言 本系统支持报警联动,就是某个探测器报警后,再去下发命令,通知下面的继电器警号,一般是通过串口发送,由于现场会利用现有的串口线路比如485总线,所以本系统需要做特殊处理,就是公用485通信总线 ...

  9. Qt开发经验小技巧221-225

    在对表格数据模型操作的时候,经常遇到一种场景就是,删除某条记录后,希望重新选中某一行.QTableView.QTableWidget本身就支持多选全选等操作,比如批量删除可以多选. //拿到表格数据模 ...

  10. Qt音视频开发42-人脸识别客户端

    一.前言 人脸识别客户端程序,不需要和人脸识别相关的库在一起,而是通过协议通信来和人脸识别服务端通信交互,人脸识别客户端和服务端程序框架,主要是为了提供一套通用的框架,按照定好的协议,实现人脸识别的相 ...