欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET適配HarmonyOS進(jìn)展的方法

 更新時間:2025年03月01日 09:06:19   作者:布布(CeSun)  
本文介紹了.NET適配鴻蒙系統(tǒng)(HarmonyOS)的進(jìn)展,包括運行時選擇、NativeAOT支撐、已知問題及解決辦法等,作者詳細(xì)分享了在移植Avalonia到HarmonyOS過程中遇到的問題及其解決方案,感興趣的朋友一起看看吧

1. 前言

目前國產(chǎn)化系統(tǒng)浪潮下,適配鴻蒙是中國軟件大勢所趨,.NET作為最適合開發(fā)客戶端語言之一,適配鴻蒙系統(tǒng)(HarmonyOS Next)是目前.NET開發(fā)者最關(guān)心的事情。我目前業(yè)余時間正在移植Avalonia到HarmonyOS,去年在.NET Conf CN上分享過,目前又取得一點進(jìn)展,所以本文把所有問題進(jìn)行整合與大家進(jìn)行分享。

2. 項目狀態(tài)

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

Avalonia移植項目在真機上也可以運行,本文主要探討.NET適配相關(guān)工作。

3. 運行時

自HarmonyOS 5.0.0(12)起,禁止匿名內(nèi)存申請可執(zhí)行權(quán)限,除系統(tǒng)內(nèi)置的JavaScript引擎外,其他虛擬機不能使用Jit功能,所以無法將CoreCLR接入到鴻蒙系統(tǒng)中,而最新版的Mono雖然支持解釋執(zhí)行,但是由于性能問題也不會接入Mono到鴻蒙系統(tǒng),最終只能選擇接入NativeAOT運行時。

4. NativeAOT

支撐鴻蒙可以接入NativeAOT的原理是鴻蒙系統(tǒng)兼容libc是musl的Linux系統(tǒng)的動態(tài)庫(.so)。而.NET的RID支持linux-musl-arm64/linux-musl-x64,所以理論上可以將.NET程序編譯為原生的Linux動態(tài)庫(.so),然后在鴻蒙的原生項目中,通過dlopen以及dlsym等函數(shù)調(diào)用C#中的入口函數(shù)。

而C#調(diào)用鴻蒙api則通過P/Invoke調(diào)用鴻蒙的NDK,而ArkUI的TypeScript api則通過NDK中的napi調(diào)用。

具體做法可以參考我正在做的Avalonia移植項目: https://github.com/OpenHarmony-NET/OpenHarmony.Avalonia

5. 已知問題

5.1 syscall限制 (已解決)

鴻蒙系統(tǒng)使用了seccomp限制危險的syscall調(diào)用。標(biāo)準(zhǔn)posix下,如果系統(tǒng)不支持某個syscall則返回錯誤碼,而seccomp非常激進(jìn),如果調(diào)用了非法的sycall則直接殺掉進(jìn)程。.NET的運行時初始化時,會調(diào)用__NR_get_mempolicy系統(tǒng)調(diào)用對numa支持進(jìn)行檢查,而這個系統(tǒng)調(diào)用不在鴻蒙的seccomp白名單中,所以導(dǎo)致直接宕機。

鴻蒙系統(tǒng)中seccomp的系統(tǒng)調(diào)用白名單如下:https://gitee.com/openharmony/startup_init/blob/master/services/modules/seccomp/seccomp_policy/app.seccomp.policy

其實安卓中也有類似的限制,.NET的NativeAOT之所以能在安卓平臺下運行是因為.NET中對安卓進(jìn)行了特殊處理,而在鴻蒙平臺我們使用的是Linux平臺的代碼,所以沒有對這些系統(tǒng)調(diào)用進(jìn)行處理。

解決辦法則是自行修改代碼,將numa的函數(shù)全部修改為空函數(shù)。

5.2 mmap申請?zhí)摂M內(nèi)存過大(已解決)

解決上個問題后,.NET運行時初始化依然不能成功,導(dǎo)致程序崩潰,經(jīng)過排查發(fā)現(xiàn)是GC初始化時會申請256G左右的虛擬內(nèi)存,導(dǎo)致mmap返回Out Of Memory錯誤。

解決辦法1:設(shè)置環(huán)境變量“DOTNET_GCHeapHardLimit”,將虛擬內(nèi)存申請控制在約180G以下即可。

解決辦法2:修改源代碼,將USE_REGIONS宏關(guān)掉。

5.3 ICU,OpenSSL等第三方庫缺失(已解決)

解決方案1:從Alpine上偷包 ,因為Alpine的libc是musl,所以理論上Alpine的庫在鴻蒙上大部分都能使用。

阿里云Alpine軟件包鏡像地址:
arm64架構(gòu):https://mirrors.aliyun.com/alpine/edge/main/aarch64/amd64架構(gòu):https://mirrors.aliyun.com/alpine/edge/main/x86_64/

解決方案2:如果該庫有cmake項目,則可以通過鴻蒙的CMake工具鏈編譯。

5.4 ICU初始化失?。ㄒ呀鉀Q)

鴻蒙的ICU配置文件路徑與默認(rèn)路徑不同,需要調(diào)用修改環(huán)境變量API,將ICU_DATA修改為/system/usr/ohos_icu
且鴻蒙平臺上libICU的大版本是72,要使用這個版本的庫。

5.5 NativeAOT如何跨平臺編譯 (Windows平臺已解決)

NativeAOT眾所周知不支持跨平臺編譯,而我的方案需要發(fā)布到linux-musl平臺,所以無法在Windows上發(fā)布,影響開發(fā)效率。

解決方案:在項目中引入項目https://github.com/OpenHarmony-NET/PublishAotCross

5.6 無法調(diào)用Marshal.GetDelegateForFunctionPointer相關(guān)函數(shù)

Marshal.GetDelegateForFunctionPointer的實現(xiàn)依賴動態(tài)生成匯編,而HarmonyOS不支持動態(tài)生成匯編代碼執(zhí)行(Jit),使用該函數(shù)會導(dǎo)致崩潰。

解決方案: 使用函數(shù)指針直接調(diào)用。

6. 如何修改NativeAOT代碼

前文中提到部分問題的解決方案是修改源碼,具體操作步驟如下:
修改完代碼,執(zhí)行以下命令進(jìn)行編譯(linux平臺下,需要有編譯環(huán)境):

./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

7.相關(guān)鏈接

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

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

到此這篇關(guān)于.NET適配HarmonyOS進(jìn)展的文章就介紹到這了,更多相關(guān).NET適配HarmonyOS內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論