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
,它可以包含在客户端和服务器中。在 Binder 化模式下,使用 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