Here's how to recognize if a particular type/function/identifier in C++ code is part of the new C++ bindings or high-level C++ bindings.
Taking the examples.keyvaluestore.baseline
library as example:
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/new/key_value_store/baseline/fidl/key_value_store.test.fidl" exclude_regexp="^//.*" %}
Here are how the various FIDL elements will map to in the C++ bindings. Note that in the table “C++” refers to the new C++ bindings, and applies equally to both natural domain objects and wire domain objects. “Natural” refers to the natural domain objects in the new C++ bindings. “Wire” refers to the wire domain objects in the new C++ bindings.
Here's the most common way to set up a client:
See the canvas example for the full code listing and explanation.
Here's the most common way to implement a server:
See the canvas example for the full code listing and explanation.
The new C++ bindings supports both low-level and high-level use cases, by offering two families of generated domain objects, and corresponding client and server APIs that speak those types.
Note: prefer natural types unless optimizing for critical performance and memory allocation. Refer to the C++ tutorials.
std::vector
, std::optional
, and std::string
.zx::handle
to manage handle ownership.fidl::StringView
) and natural type representations (e.g. std::string
).zx::handle
. Note that since generated structures are views of an underlying buffer, a parent structure will only own child handles if it also owns their underlying buffer. For example, a FIDL struct owns all the handles stored inline, but a FIDL vector of structs containing handles will be represented as a vector view, which will not own the out-of-line handles.Refer to the New C++ tutorial to get started.
<<../../../../_common/_hlcpp_notice.md>>
std::vector
, std::optional
, and std::string
.zx::handle
(libzx) to manage handle ownership.std::string
) to in-place buffers (e.g. as a fidl::StringView
).Refer to the HLCPP tutorial to get started.
Category | New C++ with wire types | New C++ with natural types | High-level C++ |
---|---|---|---|
audience | drivers and performance-critical applications | high-level services | high-level services |
abstraction overhead | RAII closing of handles [^1] | heap allocation, construction, destruction | heap allocation, construction, destruction |
type safe types | enums, structs, unions, handles, protocols | enums, structs, unions, handles, protocols | enums, structs, unions, handles, protocols |
storage | stack, user-provided buffer, or heap | heap | heap |
lifecycle | manual or automatic free | automatic free (RAII) | automatic free (RAII) |
receive behavior | decode in-place | decode into heap | decode then move to heap |
send behavior | copy or vectorize | copy | copy |
calling protocol methods | free functions or proxy | free functions or proxy | call through proxies, register callbacks |
implementing protocol methods | manual dispatch or implement stub interface | implement stub interface | implement stub object, invoke callbacks |
async client | yes | yes | yes |
async server | yes (unbounded) [^2] | yes (unbounded) [^2] | yes (unbounded) |
parallel server dispatch | yes [^3] | yes [^3] | no |
generated code footprint | large | large | large |
[^1]: Generated types own all handles stored inline. Out-of-line handles e.g. those behind a pointer indirection are not closed when the containing object of the pointer goes away. In those cases, the bindings provide a fidl::DecodedValue
object to manage all handles associated with a call.
[^2]: The bindings library defined in lib/fidl can dispatch an unbounded number of in-flight transactions via fidl::BindServer
defined in lib/fidl/cpp/wire/channel.h.
[^3]: The bindings library lib/fidl enables parallel dispatch using the EnableNextDispatch()
API defined in lib/fidl/cpp/wire/async_transaction.h.