除少数例外情况外,HIDL 接口软件包位于 hardware/interfaces 或 vendor/ 目录中。hardware/interfaces 顶层目录直接映射到 android.hardware 软件包命名空间;版本是软件包(而非接口)命名空间下的子目录。
hidl-gen 编译器将 .hal 文件编译成一组 .h 和 .cpp 文件。从这些自动生成的文件中,构建了客户端/服务器实现链接到的共享库。构建此共享库的 Android.bp 文件由 hardware/interfaces/update-makefiles.sh 脚本自动生成。每次向 hardware/interfaces 添加新软件包,或向/从现有软件包添加/删除 .hal 文件时,都必须重新运行该脚本,以确保生成的共享库是最新的。
例如,IFoo.hal 示例文件应位于 hardware/interfaces/samples/1.0 中。示例 IFoo.hal 文件在 samples 软件包中创建一个 IFoo 接口
package android.hardware.samples@1.0; interface IFoo { struct Foo { int64_t someValue; handle myHandle; }; someMethod() generates (vec<uint32_t>); anotherMethod(Foo foo) generates (int32_t ret); };
生成的文件
HIDL 软件包中的自动生成文件链接到与软件包同名的单个共享库中(例如,android.hardware.samples@1.0)。共享库还导出一个头文件 IFoo.h,客户端和服务器可以包含该文件。将 hidl-gen 编译器与 IFoo.hal 接口文件作为输入一起使用时,绑定模式具有以下自动生成的文件

图 1. 编译器生成的文件。
IFoo.h。在 C++ 类中描述纯IFoo接口;它包含在IFoo.hal文件中的IFoo接口中定义的方法和类型,并在必要时转换为 C++ 类型。不包含与用于实现此接口的 RPC 机制(例如,HwBinder)相关的详细信息。该类使用软件包和版本进行命名空间划分,例如,::android::hardware::samples::IFoo::V1_0。客户端和服务器都包含此标头:客户端用于调用其上的方法,服务器用于实现这些方法。IHwFoo.h。头文件,其中包含用于序列化接口中使用的数据类型的函数的声明。开发人员绝不应直接包含此标头(它不包含任何类)。BpHwFoo.h。一个继承自IFoo的类,描述接口的HwBinder代理(客户端)实现。开发人员绝不应直接引用此类。BnHwFoo.h。一个类,它保存对IFoo实现的引用,并描述接口的HwBinder存根(服务器端)实现。开发人员绝不应直接引用此类。FooAll.cpp。一个类,其中包含HwBinder代理和HwBinder存根的实现。当客户端调用接口方法时,代理会自动编组来自客户端的参数,并将事务发送到 binder 内核驱动程序,内核驱动程序会将事务传递到另一端的存根(然后存根调用实际的服务器实现)。
这些文件的结构类似于 aidl-cpp 生成的文件(有关详细信息,请参阅HIDL 概述中的“直通模式”)。唯一独立于 HIDL 使用的 RPC 机制的自动生成文件是 IFoo.h;所有其他文件都与 HIDL 使用的 HwBinder RPC 机制相关联。因此,客户端和服务器实现绝不应直接引用除 IFoo 以外的任何内容。为了实现这一点,只需包含 IFoo.h 并链接到生成的共享库。
链接到共享库
使用软件包中任何接口的客户端或服务器都必须在以下 (1) 个位置之一包含该软件包的共享库
- 在 Android.mk 中
LOCAL_SHARED_LIBRARIES += android.hardware.samples@1.0
- 在 Android.bp 中
shared_libs: [ /* ... */ "android.hardware.samples@1.0", ],
您可能需要包含的其他库
libhidlbase |
包含标准 HIDL 数据类型。从 Android 10 开始,它还包含以前在 libhidltransport 和 libhwbinder 中的所有符号。 |
|---|---|
libhidltransport |
处理通过不同 RPC/IPC 机制的 HIDL 调用的传输。Android 10 已弃用此库。 |
libhwbinder |
Binder 特定的符号。Android 10 已弃用此库。 |
libfmq |
快速消息队列 IPC。 |
命名空间
HIDL 函数和类型(如 Return<T> 和 Void())在命名空间 ::android::hardware 中声明。软件包的 C++ 命名空间由软件包名称和版本确定。例如,hardware/interfaces 下版本为 1.2 的软件包 mypackage 具有以下特性
- C++ 命名空间 是
::android::hardware::mypackage::V1_2 - 该软件包中
IMyInterface的 完全限定名称 是:::android::hardware::mypackage::V1_2::IMyInterface。(IMyInterface是标识符,而不是命名空间的一部分)。 - 在软件包的
types.hal文件中定义的类型标识为:::android::hardware::mypackage::V1_2::MyPackageType