不成生DOM的非主流Blazor UI開源啦!

  作者之前介紹了開發中的PixUI,爲了適配Web應用採用了將C#通過Roslyn語法語義分析後轉換爲Javascript的方案,但是這樣帶來的問題是工程量較大,在短時間內無法達到生產級質量。因此在簡單評估了Blazor技術後決定暫使用Blazor WebAssembly來實現PixUI的Web端。本文記錄一些Blazor鏈接原生(C/C++)庫過程中所踩過的坑,同時爲了慶祝兒子考完10年內最難中考提前宣佈PixUI正式開放源碼,基本概念介紹請參考上一篇。

PixUI源碼: https://github.com/enjoycode/PixUI

請先安裝 dotnet workload install wasm-tools

打開PixUI.sln運行PixUI.Platform.Blazor項目

坑一: 原生函數返回結構體無法編譯鏈接的問題

  示例C結構體與函數定義如下:

typedef struct {
  uint32_t x;
  uint32_t y;
} CPoint;

CPoint get_point(); //返回結構體

此時C#封裝的Api調用上述函數在Blazor WebAssembly鏈接時會報錯,需要包裝原生函數如下:

void get_point_wasm(CPoint* cpoint);

對應的C# Api代碼爲:

public struct CPoint {
    public uint x;
    public uint y;
}

[LibraryImport("nativeLibName")]
public static partial unsafe void get_point_wasm(CPoint* cpoint);

坑二: 原生函數回調C#方法的問題

  C#的回調方法必須是靜態方法,同時標上UnmanagedCallersOnly特性,且參數不能有結構體(可以用結構體指針代替),示例如下:

[UnmanagedCallersOnly]
public static unsafe void Callback(CPoint* cpoint) { /*...*/ }

  在將C#回調方法封送給原生函數時參考如下示例,注意因Blazor WebAssembly的Bug,回調地址只能是IntPtr類型:

var callbackPtr = (IntPtr)(delegate* unmanaged<void, CPoint*>)&Callback;
c_api(callbackPtr); //將回調地址封送給原生函數

坑三: Unicode庫ICU4C的問題

  因Blazor WebAssembly生成的icudt.dat文件不包含skia庫需要的一些Feature(比如:分詞、換行等),所以需要參考https://github.com/dotnet/icu.git自己定義並重新生成該數據文件,並且配置Blazor項目替換相應的數據文件。

小結

  最後預告一下使用PixUI開發中的低代碼快速開發框架AppBox,通過內置的開發環境將傳統應用開發過程中的數據結構、業務邏輯、用戶界面等抽象爲模型,組合模型形成完整的應用。

  力量有限,歡迎感興趣的小夥伴加入共同完善!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章