Fuchsia 介面定義語言

Fuchsia 介面定義語言 (FIDL) 是用於描述 Fuchsia 程式使用的處理序間通訊 (IPC) 通訊協定。FIDL 提供簡化的宣告語法,讓提供者將介面定義為 「protocol」。支援的資料類型包括整數、浮點數、布林值、字串, 和 帳號代碼 ,直接在 Google Cloud 控制台實際操作。這些可分為更複雜的陣列 向量、結構體、資料表和聯集

請參考以下 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 訊息,以便在處理程序間傳輸
  界定範圍

在建構期間,fidlgen 後端工具會產生支援的繫結 來自 fidlc 產生的 JSON IR 程式庫。例如: fidlgen_rust 會從 JSON IR 產生 Rust 繫結。

fidl() 程式庫目標會為每個元件建立個別繫結目標 支援的語言基於 GN 的性質,這些繫結並非產生 除非已納入為依附元件

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

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

練習:Echo 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
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
fx build vendor/fuchsia-codelab/echo-fidl:echo_hlcpp

使用 GN 找出為目標產生的來源檔案,並在 編輯者:

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

查看這些檔案的內容。以下摘要說明其中幾項 產生的介面:

介面 說明
EchoMarker 用於開啟特定通訊協定的 Proxy 和要求串流。
EchoProxy 將通訊協定方法轉換為 FIDL 要求的非同步用戶端 或是透過 IPC 管道傳送的訊息數量
EchoSynchronousProxy 將通訊協定方法轉換為 FIDL 要求的同步用戶端 或是透過 IPC 管道傳送的訊息數量
EchoRequest 用來處理各種通訊協定方法傳入要求的結構化類型。
EchoRequestStream 使用串流處理透過 IPC 管道傳入的 FIDL 要求訊息。
EchoEchoStringResponder 這個回呼會以 FIDL 回應的形式,傳送每個 Proxy 要求的傳回值 撰寫新的電子郵件訊息
介面 說明
EchoPtr 將通訊協定方法轉換為 FIDL 要求的非同步用戶端 或是透過 IPC 管道傳送的訊息數量
EchoSyncPtr 將通訊協定方法轉換為 FIDL 要求的同步用戶端 或是透過 IPC 管道傳送的訊息數量
Echo 伺服器元件的抽象類別,用於覆寫和處理傳入 FIDL 要求。
EchoStringCallback 回呼,以 FIDL 回應的形式針對每個要求傳送傳回值 撰寫新的電子郵件訊息