函数

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>