Fuchsia 介面定義語言

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

請參考以下 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 來源檔案必須匯入其他程式庫中的任何宣告。

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 程式庫

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

請先為 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 Stream,用於透過 IPC 管道處理傳入的 FIDL 要求訊息。
EchoEchoStringResponder 回呼,可針對每個 Proxy 要求傳送回傳值做為 FIDL 回應訊息。

C++

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