文档章节

C++ 下面的AIDL

o
 osc_z1hvg4cu
发布于 2018/04/24 14:36
字数 1465
阅读 30
收藏 0

精选30+云产品,助力企业轻松上云!>>>

转自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).

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Android AIDL远程服务使用示例

Android AIDL远程服务使用示例 了解Android上比较强大的远程服务设计。 一、为什么要使用AIDL,他的优势有哪些呢? AIDL服务更像是 一个Server,可以为多个应用提供服务。由于使用了IDL这样类...

android技术开发
2013/08/15
553
0
binder-JAVA层机制

根据之前分析过的cpp代码,以及编写了JAVA层的代码,笔者画了一个图进行了分层 JAVA中,RPC层的代码是直接通过aidl文件生成的,cpp部分是需要我们自己编写的 那么在JAVA中就存在两个问题,就是图中...

moyokoo
2019/01/01
0
0
Android的IPC机制Binder的详解(转发)

http://blog.csdn.net/hellofeiya/article/details/8032286 第一部分 Binder的组成 1.1 驱动程序部分 驱动程序的部分在以下的文件夹中: Java代码 kernel/include/linux/binder.h kernel/dri...

LiSteven
2013/01/25
23
0
使用android studio开发工具编译GBK转换三方库iconv

网上大多教程和资源并没有从头到尾告诉怎么编译过程,这边文章教你一个对ndk编译懂的不多,又需要使用三方库,怎么办,硬着头皮搞,又无从下手,网上一堆资料,有价值的不多,到处是偏分的。...

jasezhang
06/02
0
0
Android中aidl如何import文件

如果你做Android开发,那就应该会知道aidl工具的,但是会使用aidl命令行工具的人有吗有吗有吗,如果有的话你们为神马不出来写写怎么用!!!! 用aidl命令行的如果不出意外肯定会遇见类似这样...

华宰
2011/09/08
4.4K
0

没有更多内容

加载失败,请刷新页面

加载更多

科技人文丨玻璃心:承受阈值与表达

大家好,我是SKODE。 有趣的灵魂,聊科技人文。 本系列博客地址:传送门 本文转载自B站:安慰记传送门 玻璃心是网络用语,意思是: 对负面事件的接受度很低 还有对别人可能给出的负面评价非常...

osc_u9mt0sus
38分钟前
20
0
迅睿CMS 游客不允许上传附件

游客不允许上传附件 迅睿CMS系统:https://www.xunruicms.com/ 本文档原文地址:https://www.xunruicms.com/doc/752.html...

迅睿CMS-PHP开源CMS程序
38分钟前
7
0
代理,注解,接口和实现类的小测验

* retention : 保留* policy : 策略 ps : 简单测试了一下手写代理,jdk动态代理,和cglib动态代理,根据其不同的结果分析其原理 一:测试目的 主要想看一下不同的代理模式对于目标类中方法上注...

岁一
39分钟前
12
0
V-Ray 5 For 3ds Max 正式发布:超越渲染 - 知乎

15个新功能,V-Ray5助你时间更节省,渲染更出色! 作者:ChaosGroup VRay 5 For 3ds Max 已正式发布! 2分钟视频,抢先预览新功能↓ 知乎视频 www.zhihu.com V-Ray 5 for 3ds Max 新增功能 ...

osc_o9u1um45
39分钟前
0
0
毕业的笑容和悲伤永远是校园的回忆

校园的风轻轻的拂过我的脸庞,风儿显得更加凉爽, 开满火红的凤凰树,染遍了校园的每个角落, 晚上那枝头蝉儿的竞相鸣奏,唱满了令人不舍的毕业歌, 它们彷彿告诉了我们要毕业了。 毕业典礼那...

瑾123
40分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部