Java和C ++之间的AIDL接口 [英] AIDL interface between Java and C++
问题描述
我是AIDL界面的新手.我想在使用gradle构建的Java(应用程序层)和使用cmake构建的C ++(本机层)之间实现AIDL接口.我需要使用AIDL接口在这两个进程之间传递大量数据.我能够在应用程序层中实现.aidl文件,并能够创建服务.我需要在本机层中实现一个辅助客户端,并需要传递数据.谁能建议我如何实现将要构建的cmake AIDL.
I am a new to AIDL interface. I would like to implement AIDL interface between Java(Application layer) which is build using gradle and C++(Native layer) which is build using cmake. I need to pass a chunk of data between these two processes using AIDL interface. I am able to implement a .aidl file in application layer and able to create a service. I need to implement a aidl client in native layer and need to pass data. Can anyone suggest me how to implement AIDL which is to be build cmake.
推荐答案
要获取 aidl-cpp
二进制文件,您必须使用此处和前几条说明此处.一旦设置了构建环境,就可以使用 make aidl-cpp
来构建二进制文件.然后可以找到二进制文件在 out/host/linux-x86/bin/aidl-cpp
中.获得二进制文件后,您只需要执行一次即可.您不再需要AOSP代码(尽管可以使用该代码可以快速搜索示例).
To obtain the aidl-cpp
binary, you would have to set up the AOSP source code using the instructions here and the first few instructions here. Once you have set up the build environment, you can build the binary with make aidl-cpp
. The binary can then be found e.g. in out/host/linux-x86/bin/aidl-cpp
. You only have to do this once, after you have obtained the binary you no longer need the AOSP code (though it is nice to have the code around to quickly search for examples).
关于CMake的部分,如注释中所述,一旦构建了 aidl-cpp
二进制文件,就可以使用CMake命令
Regarding the CMake part, as discussed in the comment, once you have build the aidl-cpp
binary, you can use the CMake command add_custom_target
for code generation.
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
因此,当您从cmake调用命令时,必须提供AIDL,然后提供一个目录,在其中应存储生成的头文件,并在其下存储生成的cpp文件的名称.例如. aidl-cpp ISomeInterface.aidl ./generate-headers ./generated-cpp/ISomeInterface.cpp
.如果要使用自定义数据类型(请参见此答案的最后一部分),则还必须传递 -I
标志以指向自定义数据类型的声明.
So when you call the command from cmake, you would have to provide your AIDL, then a directory in which the generated header files should be stored, and the name under which the generated cpp file should be stored. E.g. aidl-cpp ISomeInterface.aidl ./generated-headers ./generated-cpp/ISomeInterface.cpp
. If you want to use a custom data type (see the last section of this answer), you would also have to pass the -I
flag to point to the declaration of your custom data types.
使用 aidl-cpp
生成头文件和cpp文件后,即可从C ++连接到服务.这是来自AOSP源代码的示例:
Once you have generated the header files and the cpp file with aidl-cpp
, you can then connect to your service from C++. Here is an example from the AOSP source code:
-
有一个名为由AIDL定义的接口实现为
The interface defined by the AIDL is implemented as
DropboxManagerService
in Java.该服务是从C ++ 此处:
The service is called from C++ here:
Note the include of
<com/android/internal/os/IDropBoxManagerService.h
at the beginning of the file (link). This is the header file that has been generated byaidl-cpp
from the AIDL file.
默认服务管理器用于查找名为
"dropbox"
的服务:The default service manager is used to look-up the service called
"dropbox"
:defaultServiceManager()->getService(android::String16("dropbox"))
-
getService
的结果将转换为生成的头文件中定义的接口: The result from
getService
is cast to the interface defined in the generated header file:sp<IDropBoxManagerService> service = interface_cast<IDropBoxManagerService>(...)
-
service
对象现在包含一个代理对象,您可以在其上调用AIDL中定义的方法.然后,代理对象将通过Binder将这些调用转发到Java服务(这在aidl-cpp
生成的cpp文件中实现). The
service
object now holds a proxy object on which you can call the methods defined in the AIDL. The proxy object will then forward these calls via Binder to the Java service (this is implemented in the cpp file generated byaidl-cpp
).例如,AIDL定义了方法
void add(在DropBoxManager.Entry条目中);
.C ++代码使用Status status = service-> add(entry);
调用此方法.您可以使用status.isOk()
检查事务处理的结果.For example, the AIDL defines a method
void add(in DropBoxManager.Entry entry);
. The C++ code calls this method withStatus status = service->add(entry);
. You can check the result of the transaction withstatus.isOk()
.关于数据类型,您可以找到一个表,其中包含C ++类型到Java类型的映射
Regarding data types, you can find a table with the mapping of C++ types to Java types here.
如果要发送自定义对象,则必须定义一个C ++类和一个Java类,它们都实现了
Parcelable
接口.此接口需要实现两种方法:C ++中的writeToParcel
/readFromParcel
和Java中的writeToParcel
/createFromParcel
.您将必须在每一侧提供匹配的实现,以便调用例如C ++对象上的writeToParcel
产生一种简单的二进制编码,Java端的readFromParcel
可以读取.If you want to send custom objects, you would have to define a C++ class and a Java class, which both implement the
Parcelable
interface. This interface requires to implement two methodswriteToParcel
/readFromParcel
in C++ andwriteToParcel
/createFromParcel
in Java. You would have to provide matching implementations on each side, so that calling e.g.writeToParcel
on the C++ object produces a flat binary encoding that can be read byreadFromParcel
on the Java side.您还必须使用
cpp_header
指令提供一个指向您的自定义对象的标头的AIDL文件.请参见以下示例:You would also have to provide an AIDL file that points to the header for your custom object using the
cpp_header
directive. See the following example:-
在上一部分的
DropBoxManagerService
示例中,我们看到了一个Entry
类型的对象.
In the
DropBoxManagerService
example from the previous section, we saw an object of typeEntry
.
-
在C ++方面,该类声明为此处.
On the Java side, the class is defined here.
在AIDL中,一个包裹被声明为此处.请注意,这并没有定义任何实现细节,它只是声明存在该名称的类.它还指向C ++标头,该标头将包含在
aidl-cpp
中.In AIDL, a parcelable is declared here. Note this does not define any implementation details, it just declares there is a class of this name. It also points to the C++ header, which will be included by
aidl-cpp
.在上一个示例中查看的
DropBoxManagerService
的AIDL导入了可打包The AIDL for the
DropBoxManagerService
that we looked at in the previous example imports the AIDL for the parcelable here. This allows to use this data type in the AIDL method declarations.基于这些步骤,然后可以将C ++中定义的
Entry
类从C ++发送到Java.将Entry
对象传递给C ++中的代理对象时,由aidl-cpp
生成的cpp将使用为该实现而实现的writeToParcel
函数Entry
类,用于将该类序列化为平面二进制编码.在Java端,将接收编码,并根据该编码构造一个Entry
Java对象.Based on these steps, the
Entry
class defined in C++ can then be send from C++ to Java. When passing theEntry
object to the proxy object in C++, the cpp that was generated byaidl-cpp
will use thewriteToParcel
function implemented for theEntry
class to serialize the class into a flat binary encoding. On the Java side, the encoding is received and anEntry
Java object is constructed from the encoding.这篇关于Java和C ++之间的AIDL接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-