blob: 19dd75807d25b1d3a4275fb34aa0c9b6fb7738e5 [file] [log] [blame]
<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&lt;T&gt;</code> 对象中函数的值返回。</li>
<li>如果情况更复杂,<code>generates</code> 返回值则会通过随函数调用本身一起提供的回调参数返回,而函数则返回 <code>Return&lt;void&gt;</code></li>
<li>如果不存在 <code>generates</code> 语句,函数则会返回 <code>Return&lt;void&gt;</code></li>
</ul>
<p>RPC 调用可能偶尔会遇到传输错误,例如服务器终止,传输资源不足以完成调用,或传递的参数不允许完成调用(例如缺少必需的回调函数)。<code>Return</code> 对象会存储传输错误指示以及 <code>T</code> 值(<code>Return&lt;void&gt;</code> 除外)。</p>
<p>由于客户端和服务器端函数具有相同的签名,因此服务器端函数必须返回 <code>Return</code> 类型(即使其实现并不会指出传输错误)。<code>Return&lt;T&gt;</code> 对象会使用 <code>Return(myTValue)</code> 进行构建(也可以通过 <code>mTValue</code> 隐式构建,例如在 <code>return</code> 语句中),而 <code>Return&lt;void&gt;</code> 对象则使用 <code>Void()</code> 进行构建。</p>
<p><code>Return&lt;T&gt;</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&lt;T&gt;</code> 对象中提供返回值 <code>T</code>,该值可以从基元类型 <code>T</code> 隐式生成。例如:</p>
<pre class="prettyprint">
Return&lt;uint32_t&gt; someMethod() {
uint32_t return_data = ...; // Compute return_data
return return_data;
};
</pre>
<p>另外,您还可以使用 <code>Return&lt;*&gt;::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&lt;void&gt;</code> 类型。服务器实现仅负责提供返回值。由于返回值已使用回调传输,因此 <code>T</code> 模板参数为 <code>void</code>
</p>
<pre class="prettyprint">
Return&lt;void&gt; someMethod(someMethod_cb _cb);
</pre>
<p>服务器实现应从其 C++ 实现中返回 <code>Void()</code>(这是一个可返回 <code>Return&lt;void&gt;</code> 对象的静态内嵌函数)。具有回调参数的典型服务器方法实现示例:</p>
<pre class="prettyprint">
Return&lt;void&gt; someMethod(someMethod_cb _cb) {
// Do some processing, then call callback with return data
hidl_vec&lt;uint32_t&gt; vec = ...
_cb(vec);
return Void();
};
</pre>
<h2 id="no-return">没有返回值的函数</h2>
<p>没有 <code>generates</code> 语句的函数的 C++ 签名将不会在参数列表中有任何回调参数。它的返回类型将为 <code>Return&lt;void&gt;.</code></p>
<h2 id="oneway">单向函数</h2>
<p><code>oneway</code> 关键字标记的函数是异步函数(其执行不会阻塞客户端),而且没有任何返回值。<code>oneway</code> 函数的 C++ 签名将不会在参数列表中有任何回调参数,而且其 C++ 返回值将为 <code>Return&lt;void&gt;</code></p>
</body></html>