转自https://android.googlesource.com/platform/system/tools/aidl/+/brillo-m10-dev/docs/aidl-cpp.md。

Background

“aidl” refers to several related but distinct concepts:

  • the AIDL interface definition language
  • .aidl files (which contain AIDL)
  • the aidl generator which transforms AIDL into client/server IPC interfaces

The aidl generator is a command line tool that generates client and server stubs for Binder interfaces from a specification in a file with the .aidl extension. For Java interfaces, the executable is called aidl while for C++ the binary is called aidl-cpp. In this document, we’ll use AIDL to describe the language of .aidl files and aidl generator to refer to the code generation tool that takes an .aidl file, parses the AIDL, and outputs code.

Previously, the aidl generator only generated Java interface/stub/proxy objects. C++ Binder interfaces were handcrafted with various degrees of compatibility with the Java equivalents. The Brillo project added support for generating C++ with the aidl generator. This generated C++ is cross-language compatible (e.g. Java clients are tested to interoperate with native services).

Overview

This document describes how C++ generation works with attention to:

  • build interface
  • cross-language type mapping
  • implementing a generated interface
  • C++ parcelables
  • cross-language error reporting
  • cross-language null reference handling
  • cross-language integer constants

Detailed Design

Build Interface

Write AIDL in .aidl files and add them to LOCAL_SRC_FILES in your Android.mk. If your build target is a binary (e.g. you include $(BUILD_SHARED_LIBRARY)), then the generated code will be C++, not Java.

AIDL definitions should be hosted from the same repository as the implementation. Any system that needs the definition will also need the implementation (for both parcelables and interface). If there are multiple implementations (i.e. one in Java and one in C++), keep the definition with the native implementation. Android now has systems that run the native components of the system without the Java.
If you use an import statement in your AIDL, even from the same package, you need to add a path to LOCAL_AIDL_INCLUDES. This path should be relative to the root of the Android tree. For instance, a file IFoo.aidl defining com.example.IFoo might sit in a folder hierarchy something/something-else/com/example/IFoo.aidl. Then we would write:

LOCAL_AIDL_INCLUDES := something/something-else

Generated C++ ends up in nested namespaces corresponding to the interface’s package. The generated header also corresponds to the interface package. So com.example.IFoo becomes ::com::example::IFoo in header “com/example/IFoo.h”.
Similar to how Java works, the suffix of the path to a .aidl file must match the package. So if IFoo.aidl declares itself to be in package com.example, the folder structure (as given to LOCAL_SRC_FILES
) must look like: some/prefix/com/example/IFoo.aidl
.
To generate code from .aidl files from another build target (e.g. another binary or java), just add a relative path to the .aidl files to LOCAL_SRC_FILES. Remember that importing AIDL works the same, even for code in other directory hierarchies: add the include root path relative to the checkout root to LOCAL_AIDL_INCLUDES.

Type Mapping

The following table summarizes the equivalent C++ types for common Java types and whether those types may be used as in/out/inout parameters in AIDL interfaces.

Java Type C++ Type inout Notes
boolean bool in "These 8 types are all considered primitives.
byte int8_t in  
char char16_t in  
int int32_t in  
long int64_t in  
float float in  
double double in  
String String16 in Supports null references.
android.os.Parcelable android::Parcelable inout  
T extends IBinder sp in  
Arrays (T[]) vector inout May contain only primitives, Strings and parcelables.
List vector inout  
PersistableBundle PersistableBundle inout binder/PersistableBundle.h
List vector<sp> inout  
FileDescriptor ScopedFd inout nativehelper/ScopedFd.h

Note that java.util.Map and java.utils.List are not good candidates for cross language communication because they may contain arbitrary types on the Java side. For instance, Map is cast to Map<String,Object> and then the object values dynamically inspected and serialized as type/value pairs. Support exists for sending arbitrary Java serializables, Android Bundles, etc.

Implementing a generated interface

Given an interface declaration like:

package foo;
import bar.IAnotherInterface;
interface IFoo {
IAnotherInterface DoSomething(int count, out List<String> output);
}

aidl-cpp will generate a C++ interface:

namespace foo {

// Some headers have been omitted for clarity.
#include <android/String16.h>
#include <cstdint>
#include <vector>
#include <bar/IAnotherInterface.h> // Some class members have been omitted for clarity.
class IFoo : public android::IInterface {
public:
virtual android::binder::Status DoSomething(
int32_t count,
std::vector<android::String16>* output,
android::sp<bar::IAnotherInterface>* returned_value) = 0;
};

Note that aidl-cpp
will import headers for types used in the interface. For imported types (e.g. parcelables and interfaces), it will import a header corresponding to the package/class name of the import. For instance, import bar.IAnotherInterface
causes aidl-cpp to generate #include <bar/IAnotherInterface.h>
.
When writing a service that implements this interface, write:

#include "foo/BnFoo.h"

namespace unrelated_namespace {

class MyFoo : public foo::BnFoo {
public:
android::binder::Status DoSomething(
int32_t count,
std::vector<android::String16>* output,
android::sp<bar::IAnotherInterface>* returned_value) override {
for (int32_t i = 0; i < count; ++i) {
output->push_back(String16("..."));
}
*returned_value = new InstanceOfAnotherInterface;
return Status::ok();
}
}; // class MyFoo } // namespace unrelated_namespace

Note that the output values, output and returned_value are passed by pointer, and that this pointer is always valid.

C++ Parcelables

In Java, a parcelable should extend android.os.Parcelable and provide a static final CREATOR field that acts as a factory for new instances/arrays of instances of the parcelable. In addition, in order to be used as an out parameter, a parcelable class must define a readFromParcel method.
In C++, parcelables must implement android::Parcelable from binder/Parcelable.h in libbinder. Parcelables must define a constructor that takes no arguments. In order to be used in arrays, a parcelable must implement a copy or move constructor (called implicitly in vector).
The C++ generator needs to know what header defines the C++ parcelable. It learns this from the cpp_header
directive shown below. The generator takes this string and uses it as the literal include statement in generated code. The idea here is that you generate your code once, link it into a library along with parcelable implementations, and export appropriate header paths. This header include must make sense in the context of the Android.mk that compiles this generated code.
// ExampleParcelable.aidlpackage com.example.android;// Native types must be aliased at their declaration in the appropriate .aidl// file. This allows multiple interfaces to use a parcelable and its C++// equivalent without duplicating the mapping between the C++ and Java types.// Generator will assume bar/foo.h declares class// com::example::android::ExampleParcelableparcelable ExampleParcelable cpp_header "bar/foo.h";

Null Reference Handling

The aidl generator for both C++ and Java languages has been expanded to understand nullable annotations.
Given an interface definition like:

interface IExample {
void ReadStrings(String neverNull, in @nullable String maybeNull);
};

the generated C++ header code looks like:

class IExample {
android::binder::Status ReadStrings(
const android::String16& in_neverNull,
const std::unique_ptr<android::String16>& in_maybeNull);
};

Note that by default, the generated C++ passes a const reference to the value of a parameter and rejects null references with a NullPointerException sent back the caller. Parameters marked with @nullable are passed by pointer, allowing native services to explicitly control whether they allow method overloading via null parameters. Java stubs and proxies currently do nothing with the @nullable annotation.
Consider an AIDL type in @nullable List<String> bar. This type indicates that the remote caller may pass in a list of strings, and that both the list and any string in the list may be null. This type will map to a C++ type unique_ptr<vector<unique_ptr<String16>>>* bar
. In this case:

  • bar is never null
  • *bar might be null
  • (*bar)->empty() could be true
  • (**bar)[0] could be null (and so on)

Exception Reporting

C++ methods generated by the aidl generator return android::binder::Status objects, rather than android::status_t. This Status object allows generated C++ code to send and receive exceptions (an exception type and a String16 error message) since we do not use real exceptions in C++. More background on Status objects can be found here.

For legacy support and migration ease, the Status object includes a mechanism to report a android::status_t. However, that return code is interpreted by a different code path and does not include a helpful String message.

For situations where your native service needs to throw an error code specific to the service, use Status::fromServiceSpecificError(). This kind of exception comes with a helpful message and an integer error code. Make your error codes consistent across services by using interface constants (see below).

Integer Constants

AIDL has been enhanced to support defining integer constants as part of an interface:

 interface IMyInterface {
const int CONST_A = 1;
const int CONST_B = 2;
const int CONST_C = 3;
...
}

These map to appropriate 32 bit integer class constants in Java and C++ (e.g. IMyInterface.CONST_A
and IMyInterface::CONST_A
respectively).

C++ 下面的AIDL的更多相关文章

  1. eclipse 下面的folder,source folder,package的区别与作用

    首先明确一点,folder,source folder,package都是文件夹,既然是文件夹,那么任何的文件都可以往这三种文件夹下面的放.1.他们的区别folder就是普通的文件夹,它和我们wind ...

  2. 根据div 标签 查看数组@class=modulwrap 下面的/table/tbody/tr/td

    <div class="modulwrap"> <div class="request_title"> <span class=& ...

  3. jz2440: linux/arch/arm/下面的plat-和mach-

    jz2440: linux/arch/arm/下面的plat和mach plat-s3c24xxmach-s3c2440mach-s3c2410 ====================== 1. 三 ...

  4. syslog之三:建立Windows下面的syslog日志服务器

    目录: <syslog之一:Linux syslog日志系统详解> <syslog之二:syslog协议及rsyslog服务全解析> <syslog之三:建立Window ...

  5. webkit下面的CSS设置滚动条

    webkit下面的CSS设置滚动条 1.主要有下面7个属性: ::-webkit-scrollbar 滚动条整体部分,可以设置宽度啥的 ::-webkit-scrollbar-button 滚动条两端 ...

  6. Lazarus下面的javascript绑定另外一个版本bug修正

    Lazarus下面的javascript绑定另外一个版本bug修正 从svn 检出的代码有几个问题 1.fpcjs.pas 单元开始有 {$IFDEF FPC} {$MODE delphi} {$EN ...

  7. 给虚拟机下面的ubuntu系统增加硬盘存储空间

    给虚拟机下面的ubuntu系统增加硬盘存储空间   由于ubuntu系统是安装在vsphere上面的,所以可能会和vmware上面的有一点区别,打开exsi系统的配置页面,如下图所示. 选择添加存储器 ...

  8. Java:concurrent包下面的Map接口框架图(ConcurrentMap接口、ConcurrentHashMap实现类)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  9. Java:concurrent包下面的Collection接口框架图( CopyOnWriteArraySet, CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

随机推荐

  1. 王者荣耀交流协会 -- 第5次Scrum会议

    Scrum master : 任思佳 要求1 : 工作照片 照片由王超同学拍摄 ,王露芝同学(外援)没有参加本次会议. 要求2 : 时间跨度:2017年10月17日 18:00 - 18:25 共计2 ...

  2. Linux跨服务器发送文件

    在要发送的文件所在的目录下,输入下列命令 第一种: scp -r test.jar root@127.0.0.1:$(pwd)/test.jar 其中root为服务器账户名,127.0.0.1为要发送 ...

  3. 在jsp中应如何避免,request.getContextPath();等get报错问题

    导致request中的大部分get方法无法获取,是因为没有依赖的jar包.就像这样.这里不仅仅有getContextPath()方法报错,如果存在这个问题,大部分的request方法都不可用. 解决这 ...

  4. 开发一个简单的postgresql extension

      主要是学习如何编写一个简单的pg extension,参考https://severalnines.com/blog/creating-new-modules-using-postgresql-c ...

  5. Day 08 文件操作模式,文件复制,游标

    with open:将文件的释放交给with管理 with open('文件', '模式', encoding='utf-8') as f:    # 操作    pass​ a模式:追加写入 # t ...

  6. 域名到站点的负载均衡技术一览(主要是探讨一台Nginx抵御大并发的解决方案)(转)https://www.cnblogs.com/EasonJim/p/7823410.html

    一.问题域 Nginx.LVS.Keepalived.F5.DNS轮询,往往讨论的是接入层的这样几个问题: 1)可用性:任何一台机器挂了,服务受不受影响 2)扩展性:能否通过增加机器,扩充系统的性能 ...

  7. 将SQL for xml path('')中转义的字符正常显示

    在工作中出现的发送邮件的时候:因为邮件内容中有链接,并且多个拼接在一起的,于是用了for xml path().       但是,这样显示出来的链接时会将路径中的<,>,&符号转 ...

  8. 半分钟学会使用markdown基本语法

    想看文字版的看这个吧https://www.jianshu.com/p/191d1e21f7ed

  9. json 数据在textarea中显示的时候,切换 beauty和ugly模式

    转化为beauty模式 var jsonText = $('#json').val(); $('#json').val(JSON.stringify(JSON.parse(jsonText), nul ...

  10. 3.STM32复位系统

    一.概念 复位: 使系统结束当前运行状态,重新开始运行,并根据复位种类,将系统的寄存器(特定的寄存器除外)恢复到默认状态. 二.复位的种类 1.系统复位 将除了系统后备区域寄存器(BKP)和时钟控制寄 ...