Fuchsia 介面定義語言

Fuchsia 介面定義語言 (FIDL) 是用來描述 Fuchsia 程式使用的處理序間通訊 (IPC) 通訊協定的語言。FIDL 提供簡化的宣告語法,讓供應商將介面定義為通訊協定。支援的資料類型包括整數、浮點數、布林值、字串和 這些項目可整理成更複雜的陣列、向量、結構體、資料表和聯集。

請參考下列 Echo 介面範例 FIDL 通訊協定:

library fuchsia.examples;

const MAX_STRING_LENGTH uint64 = 32;

@discoverable
closed protocol Echo {
    strict EchoString(struct {
        value string:MAX_STRING_LENGTH;
    }) -> (struct {
        response string:MAX_STRING_LENGTH;
    });
    strict SendString(struct {
        value string:MAX_STRING_LENGTH;
    });
    strict -> OnString(struct {
        response string:MAX_STRING_LENGTH;
    });
};

FIDL 通訊協定會說明透過管道傳送訊息時所叫用的一組方法。管道訊息本質上是異步的,且傳送者和接收者會各自獨立運作。FIDL 方法會引入較高層級的語意,讓您在 FIDL 交易的用戶端和伺服器端,執行更符合慣例的程式設計。

FIDL 支援下列方法類型:

  • 雙向方法:這是一般方法呼叫,可接受選用參數,且 -> 運算子後定義的傳回類型。雙向方法會在收到回應前阻斷。在 Echo 範例中,EchoString() 方法是雙向方法。
  • 單向方法:非同步方法呼叫,會立即傳回,不必等待回應。未宣告傳回類型的程式會被視為來自用戶端的單向程式。在 Echo 範例中,SendString() 方法是單向方法。
  • 事件:必要時,伺服器可能會傳送非預期的訊息給用戶端,稱為事件。事件會在 -> 運算子的傳回端宣告方法名稱。在 Echo 範例中,OnString() 方法是事件。

建立 FIDL 程式庫

FIDL 程式庫會將 FIDL 來源檔案分組。程式庫可做為所含通訊協定的命名空間,而 FIDL 來源檔案可隱含地存取同一個程式庫中的所有其他宣告。FIDL 來源檔案必須import其他程式庫的任何宣告。

Fuchsia 建構系統提供 fidl() 建構目標,可將 FIDL 來源檔案編譯成程式庫。程式庫目標的名稱必須與各來源檔案中的 library 宣告相符。請參閱以下 BUILD.gn 範例,瞭解 fuchsia.examples 程式庫:

# Import the fidl GN template.
import("//build/fidl/fidl.gni")

# Define a FIDL library target.
fidl("fuchsia.examples") {
  # FIDL source files contained in library
  sources = [
    "echo.fidl",
  ]
}

在建構期間,FIDL 編譯器 (fidlc) 前端工具會驗證並編譯程式庫來源檔案,轉換為 JSON 中介表示法 (IR)。這個 JSON IR 格式是 FIDL 繫結的基礎。

產生 FIDL 繫結

元件會透過稱為 FIDL 繫結的產生程式碼使用 FIDL 通訊協定。繫結會將要求和回應編碼及解碼為 FIDL 訊息,並透過基礎 IPC 管道傳輸。特定語言的繫結程式庫會在這些結構體周圍提供包裝函式,以便與熟悉的程式設計慣用語保持一致。

用戶端介面 (有時稱為 Proxy) 會在較高層級的函式呼叫和 FIDL 訊息之間執行轉譯作業。在伺服器端,繫結會處理傳入的要求訊息,並透過抽象介面將訊息傳送給元件執行。

圖表顯示 FIDL 繫結如何提供產生的程式庫程式碼,將函式呼叫轉譯為 FIDL 訊息,以便跨程序邊界傳輸。

在建構期間,fidlgen 後端工具會根據 fidlc 產生的 JSON IR 程式庫,為支援的程式語言產生繫結。舉例來說,fidlgen_rust 會從 JSON IR 產生 Rust 繫結。

fidl() 程式庫目標會為每種支援的語言建立個別的繫結目標。由於 GN 的特性,除非這些繫結是做為依附元件納入,否則不會在建構期間產生。

請參考下列 BUILD.gn 程式碼片段範例,其中包含 fuchsia.examples 程式庫的產生繫結目標:

荒漠油廠

deps = [
  "fidl/fuchsia.examples:fuchsia.examples_rust",
  ...
]

C++

deps = [
  "fidl/fuchsia.examples:fuchsia.examples",
  ...
]

練習:Echo FIDL 程式庫

在本節中,您將使用名為 Echo 的通訊協定定義新的 FIDL 程式庫,其中包含一個方法,可將字串值傳回給呼叫端。

請先為 FIDL 程式庫目標建立新目錄:

mkdir -p vendor/fuchsia-codelab/echo-fidl

在新專案目錄中建立下列檔案和目錄結構:

//vendor/fuchsia-codelab/echo-fidl
                        |- BUILD.gn
                        |- echo.fidl

新增名為 echo.fidl 的 FIDL 介面檔案,並在其中加入下列內容:

library fidl.examples.routing.echo;

const MAX_STRING_LENGTH uint64 = 64;

@discoverable
closed protocol Echo {
    /// Returns the input.
    strict EchoString(struct {
        value string:<MAX_STRING_LENGTH, optional>;
    }) -> (struct {
        response string:<MAX_STRING_LENGTH, optional>;
    });
};

EchoString 是雙向方法,可接受選用 (可為空值) 的字串值,並傳回相同的值。

新增含有下列內容的 BUILD.gn 檔案,以宣告程式庫目標:

import("//build/fidl/fidl.gni")
fidl("echo") {
  name = "fidl.examples.routing.echo"

  sources = [ "echo.fidl" ]

  enable_hlcpp = true
}

將程式庫目標新增至建構設定:

荒漠油廠

fx set workstation_eng.x64 --with vendor/fuchsia-codelab/echo-fidl:echo_rust

C++

fx set workstation_eng.x64 --with vendor/fuchsia-codelab/echo-fidl:echo_hlcpp

檢查 FIDL 繫結

fidl() GN 目標會編譯 FIDL 介面,並產生其他建構目標,以便提供各種語言的繫結。如要檢查繫結,您必須編譯個別目標。

編譯 fidl.examples.routing.echo 繫結:

荒漠油廠

fx build vendor/fuchsia-codelab/echo-fidl:echo_rust

C++

fx build vendor/fuchsia-codelab/echo-fidl:echo_hlcpp

使用 GN 找出目標產生的原始碼檔案,並在編輯器中開啟這些檔案:

荒漠油廠

fx gn desc out/default/ vendor/fuchsia-codelab/echo-fidl:echo_rust.actual sources

C++

fx gn desc out/default/ vendor/fuchsia-codelab/echo-fidl:echo_hlcpp sources

探索這些檔案的內容。以下摘要說明一些主要產生的介面:

荒漠油廠

介面 說明
EchoMarker 用於開啟 Proxy,並要求指定通訊協定的串流。
EchoProxy 非同步用戶端,可將通訊協定方法轉換為透過 IPC 管道傳送的 FIDL 要求訊息。
EchoSynchronousProxy 同步用戶端,可將通訊協定方法轉換為透過 IPC 管道傳送的 FIDL 要求訊息。
EchoRequest 用於處理每個通訊協定方法的傳入要求的結構化類型。
EchoRequestStream 透過串流處理透過 IPC 管道傳入的 FIDL 要求訊息。
EchoEchoStringResponder 回呼,用於將每個 Proxy 要求的回傳值傳送為 FIDL 回應訊息。

C++

介面 說明
EchoPtr 非同步用戶端,可將通訊協定方法轉換為透過 IPC 管道傳送的 FIDL 要求訊息。
EchoSyncPtr 同步用戶端,可將通訊協定方法轉換為透過 IPC 管道傳送的 FIDL 要求訊息。
Echo 伺服器元件的抽象類別,可用於覆寫及處理傳入的 FIDL 要求。
EchoStringCallback 回呼,用於將每項要求的傳回值傳送為 FIDL 回應訊息。