C # differences between struct and Classes

Source: Internet
Author: User

1. Basic working principle of jni
(1) essence of java
To understand the essence of jni, we must start with the essence of java. in essence, the java language is a scripting language (this is my personal understanding, and I hope java heroes will not use bricks to pat me ), its operation relies entirely on the script engine to explain and execute java code (of course, modern java is much more advanced and can be compiled from source code. class and other binary files in the intermediate format, this processing will greatly accelerate the java Script running speed, but the basic execution method remains unchanged, and is executed by the script engine (we call it JVM, compared with pure scripts such as python and perl, it only converts the script into a binary format. in addition, java supports the object-oriented concept well and has a complete functional library for calling. This script engine is transplanted to all platforms, this script will naturally implement the so-called "cross-platform ). the vast majority of script engines support a very significant feature, that is, they can use c/c ++ to write modules and call these modules in the script to compare them with java, java must provide a mechanism to call modules written in c/c ++ in a script to become a relatively complete script engine.
(2) java in android
The android platform is essentially composed of an arm-linux operating system and a Java virtual machine called dalvik. all the gorgeous interfaces seen on the android simulator are written in java (see the framework/base Directory of the android platform source code ). currently, dalvik only provides a standard Java virtual machine environment that supports jni calls. all hardware-related operations on the android platform are encapsulated using the jni technology. java calls the jni module, the jni module uses c/c ++ to call the underlying arm-linux driver of android.
For example, there is a file named "EGLDisplaySurface. cpp" under the frameworks/base/libs/ui Directory, which contains:
Status_t EGLDisplaySurface: In the mapFrameBuffer () function, there is an initialization code for framebuffer in arm-linux of android.
This also confirms that android is actually built on java + jni. hoho, as a result, highlights the importance of jni in android Development (of course, some simple small programs can be done with only java ).
"Jni" subdirectory, which will be used to store. c files.
(3) Compile the java call class of the jni Module
This is inevitable. For jni, a caller must be able to add an original file named JniModule. java in the innermost directory of src. It looks as follows:
Java code:
Public class JniModule {
Static {
System. loadLibrary ("aaaa ");
}
Public native static int jni_add (int a, int B );
}
Copy code
Note that we will eventually generate a name called libaaaa. so's arm-compatible binary dynamic library, but in the use of System. when loadLibrary is dynamically loaded, you only need to enter lib and. the so name is aaaa. The function of this experiment is only to calculate the sum of two numbers a and B and to print log logs to logcat in the C language module of jni.
In JniTest. java, we can call this class as follows:
Java code:
Public void onClick (View v ){
String ss;
Int a = 3;
Int B = 4;
Ss = "";
Switch (v. getId ()){
Case R. id. button1:
Ss = "a =" + String. valueOf (a) + "," + "B =" + String. valueOf (B) + "," + "a + B =" +
String. valueOf (JniModule. jni_add (a, B ));
SetTitle (ss );
Break;
Case R. id. button2:
SetTitle ("button2 click ");
Break;
Case R. id. button3:
Int pid = android. OS. Process. myPid ();
Android. OS. Process. killProcess (pid );
Break;
}
}
Copy code
Note: The button3 here is very important. The function is to get the process id of the current program and then kill it explicitly!
Why? The reason is that the regular exit function in android does not really close the currently running process, but switches to the background. This is common for common java applications and can accelerate the restart of the program, but it is a nightmare for java programs with jni modules because the program is not really closed. So the libaaaa. so library will remain in the memory. At this time, if you want to replace the old so library with the new library, you need to restart the mobile phone... It is very painful, so I think of this method to directly kill myself, so the next Startup will automatically reload the latest so library.
Generate interface files for java and c Programs
Speaking of this, we will naturally think of C language. H file, the question now is how to get from. What we need to generate a java file. C/c ++ file in h format. The answer is that the javah tool is basically provided by all jdk:
Javah-classpath "java class address" <your java module location>
By using javah, you can easily integrate JniModule. The native mark of java code is converted to c/c ++. The export function defined in the H file.
The following is the makefile used for testing. I believe that anyone who understands the makefile syntax can easily understand what the makefile is doing,
In order to perform the experiment very accurately, all paths in this makefile use absolute paths. In fact, relative paths are also acceptable.
Java code:
CC = arm-none-linux-gnueabi-gcc
LD = arm-none-linux-gnueabi-ld
MV = mv
Pipeline = javah
JHFLAGS =-classpath "/home/wayne/works/workspace/JniTest/bin"
LDFLAGS =-T "/home/wayne/CodeSourcery/Sourcery_G ++ _ Lite/arm-none-linux-gnueabi/lib/ldscripts/armelf_linux_eabi.xsc"-shared
CFLAGS =-I. -I/home/wayne/works/workspace/JniTest/jni/include/linux-I/home/wayne /works/workspace/JniTest/jni-fpic
All: libaaaa. so
Com_hurraytimes_jnitest_JniModule.h:
$ (Response) $ (JHFLAGS) com. hurraytimes. jnitest. JniModule
Aaaa. o: aaaa. c com_hurraytimes_jnitest_JniModule.h
$ (CC) $ (CFLAGS)-c-o aaaa. o aaaa. c
Libaaaa. so: aaaa. o
$ (LD) $ (LDFLAGS)-o libaaaa. so aaaa. o libcutils.
$ (RM) ../libs/armeabi/libaaaa. so
$ (MV) libaaaa. so ../libs/armeabi/
Clean:
$ (RM) *. o *. so *~
Copy code
Here, we need to mention the usage of arm-none-linux-gnueabi-gcc, this compiler has been pondering how to implement the "cross compiler" function more conveniently since it reaches version 2008. in the past, arm-xxx-linux-gcc was used to compile the software on the arm-linux platform. If your chip changes from Samsung to Phillips, the entire tool chain needs to be re-compiled. in order to prevent developers (especially embedded developers on a variety of chip platforms) from installing many gcc tool chains for different chipsets on their computers, with a-T parameter, developers can use a gcc tool chain to generate executable code and linked libraries of different platforms and formats. even so, I still don't feel quite used to it. In short, thanks to CodeSourcery's considerate functions, it took me more than half an hour to figure out and query the information, what causes the jni module to fail to work on android.
Jni module packaging problems
Again, we can only use the packaging method mentioned below for Versions later than android 1.5 cupcake.
After checking the ndk script, I realized that android 1.5 can directly package the apk. so's jni library is packaged into the apk installation package, which solves the issue that even the hardcore c/c ++ developers develop their own jni components, java scripts, the transfer of an event will fulfill its mission.
In fact, the specific operation is very simple. Create the following directory under the following directory of the current project:
/Libs/armeabi
Copy the self-generated so Library to the armeabi directory. When you run ant to generate the apk release package, the so library under the/libs/armeabi directory will be automatically packaged into the apk file, and then installed directly! Very simple and convenient.
How to call jni makefile in ant
First of all, ant is a good thing. however, if it is to replace makefile, it is hard for me to stubbornly think. the makefile syntax is simple and you can click one at a time, but let's look at ant build. xml, dizzy at first glance.
Xml is good, but it's just a mess of his uncle, and he claims that it's something for people to see... everything really has some substantial use, and the data stored in xml (used to demonstrate xml like hello world is free of use) makes people look dizzy.
Ant uses xml as the basic input. I personally think it is better to follow makefile to get a relatively simple syntax.
Now let's stop complaining. Let's take a look at how to automatically call the jni makefile file for the xml implementation supported by ant in android build. xml.
The following is an example where ant is used to compile the xml of the jni module. It can be used for development and experiment with a slight modification. You can add this before </project>:
Java code:
<Target name = "mk">
<Exec dir = "./jni" executable = "make" OS = "Linux" failonerror = "true">
</Exec>
</Target>
<Target name = "mkclr">
<Exec dir = "./jni" executable = "make" OS = "Linux" failonerror = "true">
<Arg line = "clean"/>
</Exec>
</Target>
Copy code
The method of use is ant mk and ant mkclr. One is equivalent to calling make, and the other is equivalent to calling make clean. All other operations are put in makefile.
Finally, you may find a code called libcutils. a's compiled static library is "coming soon", mainly because ndk was not released even during the experiment, android phones do not have any tools such as gdbserver, and debugging is very painful. I think how weak it is. Do you need to output something to logcat ?! Therefore, the header files of cutils are extracted from the source code of the android-platform, and the binary files compiled by the android platform are directly extracted. copy the file and link it to the so library generated by my "". In this way, you can call libcutils. the log function defined in a can directly view the log output in jni through the online logcat! The ndk documentation promises to provide online debugging functions in the future android ndk development kit.
So far, the methods for compiling and writing jni by the "Tufa" have been basically recorded and explained. We must be able to have a new understanding of the nature of ndk. Instead of modifying the lines in the readme and howto documents. Cloud such as mk...
Of course, with the above underlying compilation exploration, coupled with the ndk provided. H and several runtime libraries, and even the static Binary Package compiled in the source code of the android platform, jni can implement almost any function.
In other words, once the box of Pandora is opened, it cannot be controlled by companies like google.
If you have time to write about how to use google's ndk to compile and debug the jni module...
In fact, it is mainly about the research and translation of some ndk compilation options (in fact, google's documentation has already been very clear ). The test environment is slackware 12. 0 + android 1. 5 r1 for linux + jdk 1. 6. 0_12, ndk uses android 1. 5 ndk r1 (directly decompress the package, without installation ).
1. Start with ndk Installation
When installing ndk, you need to run one ~ /Android-ndk-1. In the 5_r1/build/directory, the name is host-setup. Sh script. I read this script and found that it is mainly used to generate out/host/config. Mk file. It is mainly used to specify the judgment of the user's operating system and the supported compiler types (set cc, ar, ld and other variables in makefile)
Ndk directory introduction.
2. directory structure analysis of ndk
Enter the android-ndk-1. The 5_r1 directory shows the following directory structure:
GNUmakefile: a standard makefile file used to reference build/core/main. Mk compilation script.
README. TXT: the basic description is useless. All the useful documents are under the docs directory.
Apps/: stores the android project directory with the jni interface (the project contains java functions defined using the native keyword)
Build/: stores almost all ndk compilation scripts and necessary static link libraries.
Docs/: stores all the "official" documents of this ndk. Each document is invaluable to jni writers.
Out/: stores some intermediate temporary files, such as jni. C /. Generated during cpp file compilation. O files.
Sources/: used to store jni files. C /. Cpp source code file.
3. Basic usage
(1) Create an android Project
Go to the apps directory and run the following command:
Android create project -- target 2 -- package com. TWM -- activity NDKTest -- path. /NDKTest/project
Create an activity named NDKTest through the command line. Note that the -- path here must be set. /XXXXX/project directory. This XXXXX directory is mainly used for ndk make to differentiate different projects and projects. Write an Application. Make sure to apply the mk file. Mk is written to the XXXXX directory.
$ NDK/apps/<myapp>/Application. Mk
In addition, the command used to compile the jni library is the same:
Make APP = <your app name>
The <your app name> here is actually the XXXXX directory.
(2) Add a jni java call interface for the project
Go to the app/NDKTest/project/src/com/TWM/NdkTest directory and create a new java file (such as NDKJni. Java), and then write the code as follows:
Java code:
Package com. TWM. NdkTest;
Public class NDKJni {
Public native int MyFunc (int a, int B );
Static {
System. loadLibrary ("NDKjni ");
}
}
Copy code
MyFunc is modified using native. Therefore, this MyFunc function is a function that calls jni.
(3) Compile an Application for the java project. Mk File
This file is mainly stored in the app/NDKTest directory to inform ndk of the compiling script, which jni module is required by the current program.
It looks like this:
APP_PROJECT_PATH: = $ (call my-dir)/project ---> the project directory under the current directory contains the java interface of the jni module.
APP_MODULES: = NDKTest ---> the name of the current module is NDKTest.
(4) understand the java program package Layers
Take the current project as an example, that is, package com in the code above. TWM. NdkTest: the class name is NDKJni. Therefore, according to the package hierarchy, you can define the function according to the function naming rules of the jni file:
JNIEXPORT jint JNICALL Java_com_TWM_NdkTest_NDKJni_MyFunc (JNIEnv * env, jobject thiz, jint a, jint B );
Of course, defining the jni function manually based on the package hierarchy is still very painful. You can use the javah tool:
Mkdir-p apps/NDKTest/project/jni
Cd apps/NDKTest/project/jni
Javah-classpath "/bin/classes" com. TWM. NdkTest. NDKJni
Then a message named com_TWM_NdkTest_NDKJni is automatically generated. H file. The content is basically the same as that generated manually:
Java code:
/* Do not edit this file-it is machine generated */
# Include <jni. h>
/* Header for class com_TWM_NdkTest_NDKJni */
# Ifndef _ Included_com_TWM_NdkTest_NDKJni
# Define _ Included_com_TWM_NdkTest_NDKJni
# Ifdef _ cplusplus
Extern "C "{
# Endif
/*
* Class: com_TWM_NdkTest_NDKJni
* Method: MyFunc
* Signature: (II) I
*/
JNIEXPORT jint JNICALL Java_com_TWM_NdkTest_NDKJni_MyFunc
(JNIEnv *, jobject, jint, jint );
# Ifdef _ cplusplus
}
# Endif

Author: t80t90s

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.