| <html devsite><head> |
| <title>函数</title> |
| <meta name="project_path" value="/_project.yaml"/> |
| <meta name="book_path" value="/_book.yaml"/> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <p>HIDL 接口中的函数会映射到自动生成的 <code>IFoo</code> C++ 类声明中的方法。每个函数的名称在 C++ 中都将保持不变;下面几部分介绍了 HIDL 参数和返回值如何转换为 C++。</p> |
| |
| <h2 id="parameters">函数参数</h2> |
| <p><code>.hal</code> 文件中列出的参数会映射到 C++ 数据类型。未映射到基元 C++ 类型的参数会通过常量引用进行传递。</p> |
| |
| <p>对于具有返回值(具有 <code>generates</code> 语句)的每个 HIDL 函数,该函数的 C++ 参数列表中都有一个附加参数:使用 HIDL 函数的返回值调用的回调函数。有<strong>一种情况例外</strong>:如果 <code>generates</code> 子句包含直接映射到 C++ 基元的单个参数,则使用回调省略(回调会被移除,而返回值则会通过正常的 <code>return</code> 语句从函数返回)。<em></em></p> |
| |
| <h2 id="return-values">函数返回值</h2> |
| <p>以下函数具有返回值。</p> |
| |
| <h3 id="transport">传输错误和返回类型</h3> |
| <p><code>generates</code> 语句可以产生三种类型的函数签名:</p> |
| |
| <ul> |
| <li>如果只有一个作为 C++ 基元的返回值,<code>generates</code> 返回值会由 <code>Return<T></code> 对象中函数的值返回。</li> |
| <li>如果情况更复杂,<code>generates</code> 返回值则会通过随函数调用本身一起提供的回调参数返回,而函数则返回 <code>Return<void></code>。</li> |
| <li>如果不存在 <code>generates</code> 语句,函数则会返回 <code>Return<void></code>。</li> |
| </ul> |
| |
| <p>RPC 调用可能偶尔会遇到传输错误,例如服务器终止,传输资源不足以完成调用,或传递的参数不允许完成调用(例如缺少必需的回调函数)。<code>Return</code> 对象会存储传输错误指示以及 <code>T</code> 值(<code>Return<void></code> 除外)。</p> |
| |
| <p>由于客户端和服务器端函数具有相同的签名,因此服务器端函数必须返回 <code>Return</code> 类型(即使其实现并不会指出传输错误)。<code>Return<T></code> 对象会使用 <code>Return(myTValue)</code> 进行构建(也可以通过 <code>mTValue</code> 隐式构建,例如在 <code>return</code> 语句中),而 <code>Return<void></code> 对象则使用 <code>Void()</code> 进行构建。</p> |
| |
| <p><code>Return<T></code> 对象可以从其 <code>T</code> 值执行隐式转换,也可以执行到该值的隐式转换。您可以检查 <code>Return</code> 对象是否存在传输错误,只需调用其 <code>isOk()</code> 方法即可。这项检查不是必需的;不过,如果发生了一个错误,而您未在 <code>Return</code> 对象销毁前对该错误进行检查,或尝试进行了 <code>T</code> 值转换,则客户端进程将会终止并记录一个错误。如果 <code>isOk()</code> 表明存在由开发者代码中的逻辑错误(例如将 <code>nullptr</code> 作为同步回调进行传递)导致的传输错误或失败调用,则可以对 Return 对象调用 <code>description()</code> 以返回适合日志记录的字符串。在这种情况下,您无法确定因调用失败而在服务器上执行的代码可能有多少。另外,您还可以使用 <code>isDeadObject()</code> 方法。此方法表明,之所以会显示 <code>!isOk()</code> 是因为远程对象已崩溃或已不存在。<code>isDeadObject()</code> 一律表示 <code>!isOk()</code>。</p> |
| |
| <h3 id="return-by">由值返回</h3> |
| <p>如果 <code>generates</code> 语句映射到单个 C++ 基元,则参数列表中不会有任何回调参数,而实现会在 <code>Return<T></code> 对象中提供返回值 <code>T</code>,该值可以从基元类型 <code>T</code> 隐式生成。例如:</p> |
| |
| <pre class="prettyprint"> |
| Return<uint32_t> someMethod() { |
| uint32_t return_data = ...; // Compute return_data |
| return return_data; |
| }; |
| </pre> |
| |
| <p>另外,您还可以使用 <code>Return<*>::withDefault</code> 方法。此方法会在返回值为 <code>!isOk()</code> 的情况下提供一个值。此方法还会自动将返回对象标记为正常,以免客户端进程遭到终止。</p> |
| |
| <h3 id="return-callback">使用回调参数返回</h3> |
| <p>回调可以将 HIDL 函数的返回值回传给调用方。回调的原型是 <code>std::function</code> 对象,其参数(从 <code>generates</code> 语句中获取)会映射到 C++ 类型。它的返回值为 void(回调本身并不会返回任何值)。</p> |
| |
| <p>具有回调参数的 C++ 函数的返回值具有 <code>Return<void></code> 类型。服务器实现仅负责提供返回值。由于返回值已使用回调传输,因此 <code>T</code> 模板参数为 <code>void</code>: |
| </p> |
| |
| <pre class="prettyprint"> |
| Return<void> someMethod(someMethod_cb _cb); |
| </pre> |
| |
| <p>服务器实现应从其 C++ 实现中返回 <code>Void()</code>(这是一个可返回 <code>Return<void></code> 对象的静态内嵌函数)。具有回调参数的典型服务器方法实现示例:</p> |
| |
| <pre class="prettyprint"> |
| Return<void> someMethod(someMethod_cb _cb) { |
| // Do some processing, then call callback with return data |
| hidl_vec<uint32_t> vec = ... |
| _cb(vec); |
| return Void(); |
| }; |
| </pre> |
| |
| <h2 id="no-return">没有返回值的函数</h2> |
| <p>没有 <code>generates</code> 语句的函数的 C++ 签名将不会在参数列表中有任何回调参数。它的返回类型将为 <code>Return<void>.</code></p> |
| |
| <h2 id="oneway">单向函数</h2> |
| <p>以 <code>oneway</code> 关键字标记的函数是异步函数(其执行不会阻塞客户端),而且没有任何返回值。<code>oneway</code> 函数的 C++ 签名将不会在参数列表中有任何回调参数,而且其 C++ 返回值将为 <code>Return<void></code>。</p> |
| |
| </body></html> |