要获取aidl-cpp二进制文件,您必须使用此处的说明和此处的前几条说明来设置 AOSP 源代码。设置构建环境后,您可以使用make aidl-cpp. 然后可以在例如 中找到该二进制文件out/host/linux-x86/bin/aidl-cpp。您只需执行一次此操作,在获得二进制文件后,您不再需要 AOSP 代码(尽管最好有代码可以快速搜索示例)。
关于 CMake 部分,正如评论中所讨论的,一旦构建了aidl-cpp二进制文件,就可以使用 CMake 命令add_custom_target来生成代码。
该aidl-cpp命令提供以下说明:
usage: aidl-cpp INPUT_FILE HEADER_DIR OUTPUT_FILE
OPTIONS:
-I<DIR> search path for import statements
-d<FILE> generate dependency file
-ninja generate dependency file in a format ninja understands
INPUT_FILE:
an aidl interface file
HEADER_DIR:
empty directory to put generated headers
OUTPUT_FILE:
path to write generated .cpp code
Run Code Online (Sandbox Code Playgroud)
因此,当您从 cmake 调用该命令时,您必须提供 AIDL,然后提供生成的头文件应存储的目录,以及生成的 cpp 文件应存储的名称。例如aidl-cpp ISomeInterface.aidl ./generated-headers ./generated-cpp/ISomeInterface.cpp。如果您想使用自定义数据类型(请参阅本答案的最后一部分),您还必须传递标志-I以指向自定义数据类型的声明。
使用 生成头文件和 cpp 文件后aidl-cpp,您就可以从 C++ 连接到您的服务。以下是 AOSP 源代码中的示例:
有一个名为 .AIDL 的文件IDropboxManagerService。
AIDL 定义的接口的实现方式与DropboxManagerServiceJava 中一样。
此处从 C++ 调用该服务:
<com/android/internal/os/IDropBoxManagerService.h请注意文件开头的包含(链接)。aidl-cpp这是从 AIDL 文件生成的头文件。
默认服务管理器用于查找名为的服务"dropbox":
defaultServiceManager()->getService(android::String16("dropbox"))
Run Code Online (Sandbox Code Playgroud)
结果被getService转换为生成的头文件中定义的接口:
sp<IDropBoxManagerService> service = interface_cast<IDropBoxManagerService>(...)
Run Code Online (Sandbox Code Playgroud)
该service对象现在拥有一个代理对象,您可以在该代理对象上调用 AIDL 中定义的方法。然后,代理对象将通过 Binder 将这些调用转发到 Java 服务(这是在 生成的 cpp 文件中实现的aidl-cpp)。
例如,AIDL定义了一个方法void add(in DropBoxManager.Entry entry);。C++ 代码使用Status status = service->add(entry);. 您可以通过 查询交易结果status.isOk()。
关于数据类型,您可以在此处找到 C++ 类型到 Java 类型的映射表。
如果要发送自定义对象,则必须定义一个 C++ 类和一个 Java 类,它们都实现该Parcelable接口。该接口需要在C++中实现两个方法writeToParcel/ ,在Java中实现/ 。您必须在每一端提供匹配的实现,以便在 C++ 对象上调用eg 生成可以在Java 端读取的平面二进制编码。readFromParcelwriteToParcelcreateFromParcelwriteToParcelreadFromParcel
您还必须提供一个 AIDL 文件,该文件指向使用该cpp_header指令的自定义对象的标头。请参见以下示例:
在DropBoxManagerService上一节的示例中,我们看到了一个类型为 的对象Entry。
在AIDL中,一个parcelable在这里被声明。请注意,这没有定义任何实现细节,它只是声明存在一个具有此名称的类。它还指向 C++ 头文件,该头文件将包含在aidl-cpp.
我们在上一个示例中查看的AIDL在此DropBoxManagerService导入了 Parcelable 的 AIDL 。这允许在 AIDL 方法声明中使用此数据类型。
基于这些步骤,EntryC++中定义的类可以从C++发送到Java。当将Entry对象传递给 C++ 中的代理对象时,生成的 cppaidl-cpp将使用writeToParcel为该类实现的函数Entry将类序列化为平面二进制编码。在 Java 端,接收编码并Entry根据编码构造 Java 对象。