Dart 2.5發布,支持Dart與C相互調用
Dart 2.5 已經發布了,其中包括兩個主要預覽新特性:機器學習(ML)驅動的代碼補全和 dart:ffi 外部函數接口,用于直接從 Dart 調用 C 代碼。Dart 2.5 還改進了對常量表達式的支持。具體如下:
ML Complete,按機器學習排序的代碼補全
通過分析 GitHub 上 Dart 代碼的大量語料庫,訓練基于給定上下文的可能出現的成員的模型來實現的,這個模型由 TensorFlow Lite 驅動,可以用來預測開發人員正要編輯的代碼,這個新特性稱為 ML Complete。
假設編寫一個小程序,用來計算從當前時間到某一天的時間。使用 ML Complete,如下所示(第一張圖)。首先,它能夠根據變量名稱為 now 自動提供 DateTime.Now () 補全 。接下來,定義變量名 tomorrow,使用 add (…) 方法。在非 ML Complete 中(第二張圖),必須手動開始輸入 Datetime 才會有提示補全,而且 add () 方法在補全提示的列表中的位置相對低。
ML Complete 可以在所有支持 Dart 的編輯器中使用,包括 Android Studio、IntelliJ 和 VS Code 等。由于該特性仍出于預覽階段,若要試用可在 Flutter dev channel 和 Dart dev channel 版。
dart:ffi 外部函數接口
目前,直接從 Dart 調用 C 的支持僅限于使用原生擴展深入集成到 Dart VM 中,或者 Flutter 應用程序可以間接調用 C,通過使用 Platform Channel 調用主機,在那里調用 C,這是一個不受歡迎的雙重間接。
Dart-C 互操作支持的兩種主要方案:
調用基于 C 的操作系統 API
調用 Linux 命令 system,該命令允許執行任何系統命令,傳遞給它的參數實際是傳遞給 shell/terminal,并在其運行。下面是這個命令的 C 頭文件:
任何互操作機制的難點在于處理兩種語言在語義上的差異。對于 dart:ffi,Dart 代碼需要做兩件事:
// C header typedef: typedef SystemC = ffi.Int32 Function (ffi.Pointer<Utf8> command); // Dart header typedef: typedef SystemDart = int Function (ffi.Pointer<Utf8> command);
然后,需要加載庫并查找要調用的函數,如何做到這一點取決于操作系統;在本例中,使用的是 MacOS:
接下來,使用與特定操作系統相關的編碼對字符串參數進行編碼,調用函數,并再次釋放參數內存:
cmdP.free ();此代碼執行系統命令,使得系統默認瀏覽器打開 dart.dev:
調用基于 C 的框架和組件
Dart 的第二個核心用途是調用基于 C 的框架和組件。如上的示例,它使用 TensorFlow Lite,一個基于 C 的 API,使用 Dart:ffi 允許在需要提供代碼完成的所有操作系統上運行 TensorFlow,并具有本機 TensorFlow 實現的高性能。
目前 dart:ffi 屬于預覽階段,所以還會有一些限制。
另外,從 Dart 2.5 開始,支持更多的方法來定義常量表達式,包括強制轉換以及在 Dart 2.3 中提供的新的控制流和集合擴展特性: