Android platform calls c++

Xiaobai: Why can't you write c or c++ code directly in java code? The oc code can be written directly!

Xiao Cheng: You can write it, but you can't compile it.

Xiaobai: That means you can't write!

Whether it is compiled to jvm or run on dalvik, the java compiler will not directly generate executable files, but only generate bytecodes (expressed as class files or converted dex files), which is similar to c/c++ compilation. The approach of the compiler is very different, and probably because of this reason, the c/c++ code cannot be mixed in java, and the objective-c can mix c/c++, because its compiler directly generates the executable file.

Can the java language use c++ code? If there is a problem, there is a solution, and the solution is to use JNI.

The emergence of JNI (java native interface, that is, java native interface) can solve the problem of interaction between java and c++, and is not limited to c++.

Xiaobai: But, why should my android program call C++ code?

Xiaocheng: There are reasons for this. For example, a certain function has been implemented in C++ code instead of Java code. For example, a large number of data operations need to be performed and the execution performance of C++ is far higher than that of Java. .

This article demonstrates how java calls C++ code, that is, the use of jni.

The jni layer can be divided into the upper jni layer and the lower jni layer.

The upper layer of jni is implemented by java, and the lower layer of jni is implemented by c/c++.

The approximate calling relationship is as follows:
call the jni layer

Xiao Cheng then introduces the implementation of the upper and lower layers of jni in detail, and introduces how to generate the so library (the so library represents the function implemented by c++) and call it.

(1) Realize the upper layer of jni

Just find a java class (or create a new one), and then declare a native method in it to implement the upper layer of jni.

For example, create an Android Studio project with a native method declaration like this:
jni upper-native method declaration

So far, the jni upper layer has been established.

(2) Realize the lower layer of jni

When the java code calls the native function of the upper layer of jni, what function of c++ will it call? There needs to be a mapping relationship here.

There are two ways to establish this mapping.

Method 1: Use a signature

For the native method, using javah, you can extract the corresponding signature, and then C++ can implement the function of this signature.

The signature can be generated like this:
Generate signature using javah

The content of this .h file is this:
Signature of native method

That long string is the corresponding signature. The c++ code implements this function, so that when java calls the native function declared by the upper layer of jni, it will be called here. Obviously, once the mapping is established, the upper and lower jni layers cannot be renamed (unless re-signed).

Xiaobai: There's a lot of them, so I don't want to change their names, it's very inhumane.

Xiaocheng: If you want to change the name, add an interface, or use the second method.

Method 2: Use RegisterNatives

RegisterNatives is called when the jni layer is loaded.

In this method, instead of using javah to generate a fixed signature, RegisterNatives is used to establish the association between the navtive method and the specific implementation, and the specific implementation can be named arbitrarily.

Inside the JNI_onLoad function, trigger the call to RegisterNatives:
JNI_onLoad function
RegisterNatvies use

After solving the mapping problem of the upper and lower layers of jni, it is the specific implementation of the natvie method. Here is how to generate a dynamic link so library.

In the root directory of the project, create a jni directory, write c/c++ code and compile scripts in it, the directory structure is as follows:
The file structure implemented by jni

Contents of impl.c:
jni implementation code

Contents of script Android.mk:
jni compile script

Execute ndk-build to generate the so library:
Execute ndk-build
so foot

You can view the so library with readelf:
View the so library with readelf

This involves the rules of compiling scripts (Android.mk), smalis language features (jni data types, etc.), as well as the use of ndk-build and other knowledge, Xiaocheng is not expanded, readers can pay attention to the "Guangzhou Xiaocheng" WeChat public number and get subsequent updates.

(3) Call the jni layer

Call native methods at the java layer, such as:
call native method

Execute this program and you can see the output:
program output

At this point, the implementation of how to call C++ on the Android platform is introduced.


To sum up, this article introduces how to call the implementation of C++ on the Android platform, demonstrates the creation of the jni layer and compiles the so library, and calls the so library. Readers can apply this part of knowledge to actual Android projects.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325217335&siteId=291194637