HIDL 接口中的函数会映射到自动生成的 IFoo
C++ 类声明中的方法。每个函数的名称在 C++ 中保持不变;以下部分介绍了 HIDL 参数和返回值如何转换为 C++。
函数参数
.hal
文件中列出的参数会映射到 C++ 数据类型。不映射到 C++ 原始类型的参数通过常量引用传递。
对于每个具有返回值的 HIDL 函数(具有 generates
语句),该函数的 C++ 参数列表都有一个额外的参数:一个回调函数,该函数使用 HIDL 函数的返回值进行调用。**有一个例外**:如果 generates
子句包含一个直接映射到 C++ 原始类型的单个参数,则会使用回调*省略*(回调被移除,返回值通过普通的 return
语句从函数返回)。
函数返回值
以下函数具有返回值。
传输错误和返回类型
generates
语句可能会导致三种类型的函数签名
- 对于只有一个作为 C++ 原始类型的返回值,
generates
返回值通过Return<T>
对象中的值从函数返回。 - 对于更复杂的情况,
generates
返回值通过函数调用本身提供的回调参数返回,并且函数返回Return<void>
。 - 对于不存在
generates
语句的情况,该函数返回Return<void>
。
RPC 调用有时可能会遇到传输错误,例如,当服务器崩溃时、当传输资源不足以完成调用时,或者当传递的参数不允许完成调用时(例如缺少所需的回调函数)。Return
对象存储传输错误指示以及 T
值(Return<void>
除外)。
由于客户端和服务器端函数具有相同的签名,因此服务器端函数必须返回 Return
类型,即使其实施不发出传输错误信号也是如此。Return<T>
对象使用 Return(myTValue)
构建(或可以从 mTValue
隐式构建,例如在 return
语句中),Return<void>
对象使用 Void()
构建。
Return<T>
对象可以隐式转换为和从其 T
值转换。可以通过调用 Return
对象的 isOk()
方法来检查传输错误。此检查不是必需的;但是,如果发生错误并且在 Return
对象被销毁或尝试 T
值转换时未进行检查,则客户端进程将被终止并记录错误。如果 isOk()
指示传输错误或由于开发者代码中的逻辑错误(例如将 nullptr
作为同步回调传递)而导致的调用失败,则可以在 Return 对象上调用 description()
以返回适合记录的字符串。在这种情况下,无法确定服务器上可能执行了多少代码以响应失败的调用。isDeadObject()
方法也已提供。此方法指示 !isOk()
是因为远程对象已崩溃或不再存在。isDeadObject()
始终意味着 !isOk()
。
按值返回
如果 generates
语句映射到单个 C++ 原语,则参数列表中没有回调参数。相反,实现会在 Return<T>
对象中提供返回值 T
,该对象可以从原语类型 T
隐式生成。例如
Return<uint32_t> someMethod() { uint32_t return_data = ...; // Compute return_data return return_data; };
还提供了 Return<*>::withDefault
方法。此方法在返回值是 !isOk()
的情况下提供一个值。此方法还会自动将返回对象标记为“正常”,以便客户端进程不会被终止。
使用回调参数返回
回调可以将 HIDL 函数的返回值传递回调用方。回调的原型是一个 std::function
对象,其参数(取自 generates
语句)映射到 C++ 类型。它的返回值是 void,回调本身不返回值。
带有回调参数的 C++ 函数的返回值类型为 Return<void>
。服务器实现仅负责提供返回值。由于返回值已使用回调传输,因此 T
模板参数为 void
Return<void> someMethod(someMethod_cb _cb);
从其 C++ 实现中,服务器实现应返回 Void()
,这是一个返回 Return<void>
对象的静态内联函数。带有回调参数的典型服务器方法实现示例
Return<void> someMethod(someMethod_cb _cb) { // Do some processing, then call callback with return data hidl_vec<uint32_t> vec = ... _cb(vec); return Void(); };
没有返回值的函数
没有 generates
语句的函数的 C++ 签名在参数列表中不会有回调参数。它的返回类型将是 Return<void>.
单向函数
用 oneway
关键字标记的函数是异步函数(客户端不会在其执行上阻塞),并且没有返回值。oneway
函数的 C++ 签名在参数列表中不会有回调参数,并且其 C++ 返回值将是 Return<void>
。