快速參考指引
以下說明如何在 C++ 程式碼中,判斷特定類型/函式/ID 是否 新 C++ 繫結部分或高階 C++ 繫結的一部分。
以 examples.keyvaluestore.baseline
程式庫為例:
library examples.keyvaluestore.baseline;
type Item = struct {
key string:128;
value vector<byte>:64000;
};
type WriteError = flexible enum {
UNKNOWN = 0;
INVALID_KEY = 1;
INVALID_VALUE = 2;
ALREADY_EXISTS = 3;
};
@discoverable
open protocol Store {
/// Writes an item to the store.
flexible WriteItem(struct {
attempt Item;
}) -> () error WriteError;
};
以下說明各種 FIDL 元素在 C++ 繫結中的對應方式。注意事項 「C++」資料表中是指新的 C++ 繫結,並同樣適用於 使用自然領域物件和通訊網域物件「自然」是指 自然領域物件「電匯」是指電線網域 新 C++ 繫結中的物件。
FIDL 元素 | C++ 自然型別 | 留言 | |
---|---|---|---|
標頭包括 | C++ | #包含 <fidl/examples.keyvaluestore.baseline/cpp/fidl.h> | 格式為「fidl/library name/cpp/fidl.h」 |
HLCPP | #包含 <範例>/keyvaluestore/baseline/cpp/fidl.h> | 格式為「斜線分隔程式庫 name/cpp/fidl.h」 | |
圖書館 | C++ | ::examples_keyvaluestore_baseline | 新的 C++ 會使用單一層級的命名空間。 HLCPP 使用巢狀命名空間。 |
HLCPP | ::examples::keyvaluestore::baseline | ||
項目結構 | 自然 | ::examples_keyvaluestore_baseline::Item | 除了命名空間差異外,線路類型也是以巢狀結構嵌入 "::wire" 底下。 |
拉線式 | ::examples_keyvaluestore_baseline::wire::Item | ||
HLCPP | ::examples::keyvaluestore::baseline::Item | ||
WriteError 列舉 | 自然 | ::examples_keyvaluestore_baseline::WriteError | 除了命名空間差異外,線路類型也會以巢狀結構列於 "::wire" 之下。 如果是列舉和位元,線路類型和自然型別則相等。只有一個類型別名。 |
拉線式 | ::examples_keyvaluestore_baseline::wire::WriteError | ||
HLCPP | ::examples::keyvaluestore::baseline::WriteError | ||
string:128 | 自然 | std::字串 | |
拉線式 | fidl::StringView | ||
HLCPP | std::字串 | ||
向量<byte>:64000 | 自然 | std::向量<uint8_t> | |
拉線式 | fidl::VectorView<uint8_t> | ||
HLCPP | std::向量<uint8_t> | ||
通訊協定存放區 | C++ | ::examples_keyvaluestore_baseline::Store | 包含通訊協定相關資訊的標記類型 |
HLCPP | ::examples::keyvaluestore::baseline::Store | 包含通訊協定中方法的抽象基本類別 | |
client_end:Store | C++ | fidl::ClientEnd<Store> | |
HLCPP | fidl::InterfaceHandle<Store> | ||
server_end:Store | C++ | fidl::ServerEnd<Store> | |
HLCPP | fidl::InterfaceRequest<Store> | ||
商店通訊協定 的用戶端和伺服器類型 |
自然 | 用戶端:fidl::Client<Store> 同步用戶端:fidl::SyncClient<Store> 伺服器介面:fidl::Server<Store> 事件處理常式介面:fidl::EventHandler<Store> |
|
拉線式 | 用戶端:fidl::WireClient<Store> 同步用戶端:fidl::WireSyncClient<Store> 伺服器介面:fidl::WireServer<Store> 事件處理常式介面:fidl::WireEventHandler<Store> |
||
HLCPP | 用戶端:fidl::InterfacePtr<Store> 同步用戶端:fidl::SynchronousInterfacePtr<Store> 伺服器介面:商店 事件處理常式介面:不適用。InterfacePtr 擁有 setter,每個事件宣告只接受一個回呼。 |
以下為最常見的用戶端設定方式:
C++ (自然)
// Connect to the protocol inside the component's namespace. This can fail so it's wrapped in a // |zx::result| and it must be checked for errors. zx::result client_end = component::Connect<examples_canvas_baseline::Instance>(); if (!client_end.is_ok()) { FX_LOGS(ERROR) << "Synchronous error when connecting to the |Instance| protocol: " << client_end.status_string(); return -1; } // Create an instance of the event handler. EventHandler event_handler(loop); // Create an asynchronous client using the newly-established connection. fidl::Client client(std::move(*client_end), dispatcher, &event_handler); FX_LOGS(INFO) << "Outgoing connection enabled";
C++ (有線)
// Connect to the protocol inside the component's namespace. This can fail so it's wrapped in a // |zx::result| and it must be checked for errors. zx::result client_end = component::Connect<examples_canvas_baseline::Instance>(); if (!client_end.is_ok()) { FX_LOGS(ERROR) << "Synchronous error when connecting to the |Instance| protocol: " << client_end.status_string(); return -1; } // Create an instance of the event handler. EventHandler event_handler(loop); // Create an asynchronous client using the newly-established connection. fidl::WireClient client(std::move(*client_end), dispatcher, &event_handler); FX_LOGS(INFO) << "Outgoing connection enabled";
HLCPP
// Connect to the protocol inside the component's namespace, then create an asynchronous client // using the newly-established connection. examples::canvas::baseline::InstancePtr instance_proxy; auto context = sys::ComponentContext::Create(); context->svc()->Connect(instance_proxy.NewRequest(dispatcher)); FX_LOGS(INFO) << "Outgoing connection enabled"; instance_proxy.set_error_handler([&loop](zx_status_t status) { FX_LOGS(ERROR) << "Shutdown unexpectedly"; loop.Quit(); });
如需完整的程式碼清單和說明,請參閱畫布範例。
以下是最常見的伺服器實作方式:
C++ (自然)
// An implementation of the |Instance| protocol. class InstanceImpl final : public fidl::Server<examples_canvas_baseline::Instance> { void AddLine(AddLineRequest& request, AddLineCompleter::Sync& completer) override { // ... } };
C++ (有線)
// An implementation of the |Instance| protocol. class InstanceImpl final : public fidl::WireServer<examples_canvas_baseline::Instance> { void AddLine(AddLineRequestView request, AddLineCompleter::Sync& completer) override { // ... } };
HLCPP
// An implementation of the |Instance| protocol. class InstanceImpl final : public examples::canvas::baseline::Instance { void AddLine(Line line) override { // ... } };
如需完整的程式碼清單和說明,請參閱畫布範例。
新的 C++ 繫結
新的 C++ 繫結同時支援低階和高階用途, 提供兩個產生的網域物件系列,以及對應的用戶端和 讀取這些類型的伺服器 API
自然型別
- 可滿足高階服務程式設計需求。
- 使用慣用的 C++ 類型表示資料結構,例如
std::vector
、std::optional
和std::string
。 - 使用智慧指標管理堆積分配的物件。
- 請使用
zx::handle
管理擁有權。 - 可在接線 (例如
fidl::StringView
) 和自然線之間轉換資料 型別表示法 (例如std::string
)。
電匯類型
- 可滿足低階系統程式設計需求,同時提供 安全性與功能略高
- 代表資料結構,其記憶體配置與電線一致 也就是滿足 C++ 標準版面配置的需求這樣就能開啟 直接編碼和解碼
- 產生的結構是基礎緩衝區的檢視區塊;非他們所有 記憶體用量
- 支援就地存取 FIDL 訊息。
- 精細控管記憶體配置。
- 使用自有帳號代碼類型,例如
zx::handle
。請注意 結構是基礎緩衝區的檢視畫面,父項結構只會 自己的子項會處理。舉例來說 FIDL 結構體擁有所有內嵌於內嵌的控制代碼,但結構體的 FIDL 向量 內含控點將以向量檢視畫面表示,但不具擁有權 運用脫字線控點
用戶端和伺服器 API
- 與 C 繫結相比,程式碼產生器產生的程式碼會更多。這包括 建構函式、解構函式、複製/移動函式、網域之間的轉換 物件系列、通訊協定用戶端實作,以及純虛擬伺服器 存取 API
- 使用者將提供的伺服器介面子類別 覆寫每項作業的純虛擬方法
- 用戶端支援同步處理和非同步呼叫,以及同步處理和非同步事件處理。
- 需要 C++17 以上版本。
如要開始使用,請參閱新的 C++ 教學課程。
高階 C++ 繫結
- 可滿足高階服務程式設計需求。
- 使用慣用的 C++ 類型表示資料結構,例如
std::vector
、std::optional
和std::string
。 - 使用智慧指標管理堆積分配的物件。
- 請使用
zx::handle
(libzx) 管理帳號代碼擁有權。 - 可以將就地的 FIDL 緩衝區資料轉換為分配的慣用堆積 如需儲存大量結構化物件 建議使用 Cloud Bigtable
- 可以從慣用的堆積分配物件中轉換資料
(例如
std::string
) 到就地緩衝區 (例如fidl::StringView
)。 - 與 C 繫結相比,程式碼產生器產生的程式碼會更多。這包括 建構函式、解構函式、通訊協定 Proxy、通訊協定虛設常式、複製/移動 函式,以及往返就地緩衝區的轉換。
- 用戶端會把提供的虛設常式分化,以執行通訊協定分派作業,並 為每個作業實作虛擬方法
- 系統支援非同步和同步用戶端。不過,非同步用戶端 不符合執行緒安全要求
- 需要 C++14 以上版本。
如要開始使用,請參閱 HLCPP 教學課程。
摘要
類別 | 支援線路類型的新 C++ | 含有自然型別的新 C++ | 高階 C++ |
---|---|---|---|
目標對象 | 能夠和著重效能的應用程式 | 高階服務 | 高階服務 |
抽象化負荷 | RAII 帳號代碼關閉1 | 堆積分配、建構、刪除 | 堆積分配、建構、刪除 |
類型安全類型 | 列舉、結構體、聯集、控點、通訊協定 | 列舉、結構體、聯集、控點、通訊協定 | 列舉、結構體、聯集、控點、通訊協定 |
儲存空間 | 堆疊、使用者提供的緩衝區或堆積 | 堆積 | 堆積 |
生命週期 | 手動或自動免費 | 自動免費 (RAII) | 自動免費 (RAII) |
接收行為 | 就地解碼 | 解碼成堆積 | 並移至堆積 |
傳送行為 | 複製或向量化 | 複製 | 複製 |
呼叫通訊協定方法 | 免費函式或 Proxy | 免費函式或 Proxy | 透過 Proxy 呼叫、註冊回呼 |
實作通訊協定方法 | 手動分派或實作虛設常式介面 | 實作虛設常式介面 | 實作虛設常式物件、叫用回呼 |
非同步用戶端 | 是 | 是 | 是 |
非同步伺服器 | 是 (無限制) 2 | 是 (不設限) [^2] | 是 (無限制) |
平行伺服器調度 | 是3 | 是 [^3] | 否 |
產生的程式碼足跡 | 大 | 大 | 大 |
-
產生的類型擁有內嵌儲存的所有控制代碼。虛線控點 例如:當包含容器時 指標的 物件會消失在這些情況下,繫結會提供
fidl::DecodedValue
物件,用於管理與呼叫相關的所有帳號代碼。↩ -
lib/fidl 中定義的繫結程式庫可以 透過
fidl::BindServer
分派不受限的傳輸中交易數量 lib/fidl/cpp/wire/channel.h.↩ -
繫結程式庫 lib/fidl 可啟用平行處理功能 傳送
EnableNextDispatch()
API lib/fidl/cpp/wire/async_transaction.h.↩