There are two ways to generate JNI: one is to generate excessive Java code from C + + code through swig, and the other is to automatically generate excessive C + + code from Java code in Javah way. The procedure in two different ways is the opposite.
The first way: Because the need to configure the Swig environment, a bit of trouble, so often people do not use this approach, referring to the blog http://my.oschina.net/liusicong/blog/314162.
The second way: The Javah method can complete the entire process through the shell instruction, which probably includes the following steps:
- Write Java code . We'll start with writing Java classes that perform three tasks: declaring a native method that will be called, loading a shared library containing native code, and then calling the native method.
compiling Java code . Before using Java classes, they must be successfully compiled into bytecode.
Create C + + header file . The C + + header file declares the description of the native function that you want to invoke. This header file then creates a shared library (see step 5), together with the C + + function implementation (see step 4).
Write C + + code . This step implements the functions in the C or C + + source code files. The C + + source file must contain the header file that you created in step 3.
Create a shared library file . Create a shared library file from the C source code file that you created in step 4.
Run Java program . Run the code and see if it is useful. We will also discuss some of the techniques used to solve common mistakes.
The second method is implemented in the following ways and examples:
1. Create a project in eclipse: Testjni
2. Create a new Class:TestJNI.java
Package com.wwj.jni; public class Testjni {public native Boolean Init (); public native int Add (int x, int y); public native void Destory ();}
The above code declares three local methods.
3. Compiling JNI
Find an Android project in the bin directory, there will be Classes folder, Eclipse automatically generated for us the bytecode file is in this directory.
We use the Javah command under this path to generate the. h header file we want to get, as shown in:
After the Javah-jni com.wwj.jni.TestJNI command is executed, the header file is generated in the classes directory: com_wwj_jni_testjni.h
Copy it to the JNI folder and open the following:
< JNI . h > / * Header for Class Com_wwj_jni_testjni */#ifndef _included_com_wwj_jni_testjni #define _included_com_wwj_jni_ Testjni #ifdef __cplusplusextern "C" {#endif/* * Class: com_wwj_jni_testjni * Method: Init * Signature: () Z */JNI EXPORT Jboolean jnicall java_com_wwj_jni_testjni_init (jnienv *, jobject);/* * Class: com_wwj_jni_testjni * Method: Add * Signature: (II) I */jniexport jint jnicall java_com_wwj_jni_testjni_add (jnienv *, Jobject, Jint, Jint)//* Class: com_wwj_jni_testjni * Method: destory * Signature: () V */ jniexport void Jnicall Java_co M_wwj_jni_testjni_destory (jnienv *, jobject); #ifdef __cplusplus} #endif #endif
The code above is to generate JNI layer code through the Javah command.
4. Implementation of JNI using C + +
Under the Jni folder, create the com_wwj_jni_testjni.h corresponding CPP file: Com_wwj_jni_testjni.cpp
We add two more file Add.h,add.cpp, the implementation is placed in these two files to complete.
Add.h
#ifndef _test_jni_add_h_ #define _TEST_JNI_ADD_H_ class CAdd {public: CAdd (); ~cadd (); int Add (int x, int y); }; #endif
Add.cpp
#include "Add.h" Cadd::cadd () {} cadd::~cadd () {} int cadd::add (int x, int y) { return x + y;}
Implementation of Com_wwj_jni_testjni.cpp:
#include<stdio. h>#include<Stdlib. h>#include "com_wwj_jni_testjni.h" #include "Add.h" Add *pcadd = NULL; Jniexport Jboolean jnicall java_com_wwj_jni_testjni_init (jnienv *env,jobject obj) {if (Pcadd = = NULL) {PCADD = new CAdd; } return Pcadd! = NULL;} Jniexport jint jnicall java_com_wwj_jni_testjni_add (jnienv *env, Jobject obj, Jint x, jint y) {int res =-1; if (pcadd! = NULL) {res = Pcadd->add (x, y); } return res; Jniexport void Jnicall java_com_wwj_jni_testjni_destory (jnienv *env, Jobject obj) {if (Pcadd! = NULL) {Pcadd = NULL; }}
5. Create the Mk file and use the Ndk-build command to generate the. So dynamic link library file
Create the Android.mk file under the JNI directory as follows:
Local_path: = $ (call My-dir) include $ (clear_vars) Local_module: = testjnilocal_src_files: = Com_wwj_jni_ Testjni.cpplocal_src_files + = Add.cppinclude $ (build_shared_library)
which
Local_path is the directory in which C + + code is located, which is our JNI directory.
Local_module is the name of the library to compile. The compiler automatically adds Lib to the front, followed by. So.
Local_src_files is a C + + file to compile.
Then I also need to create the Application.mk file in the root directory of the Android project:
App_project_path: = $ (call my-dir) App_modules: = Testjni
After writing these two MK files, we can use the NDK to generate the corresponding dynamic link library for us. If you need to download the NDK, and configure the NDK path to the PATH environment variable, the path I configured is: D:\Cocos2dx\android-ndk-r9d, depending on the individual situation.
Enter the directory where the Application.mk file is located and use Ndk-build on the command line to generate the. so file
Successful compilation generates a libtestjni.so file in the Libs/armeabi directory of the project directory.
The project structure will become as follows:
6. Invoking JNI in Java
Package Com.wwj.jni;import Android.os.bundle;import Android.widget.textview;import android.app.activity;public Class Testjniactivity extends Activity { private TextView TextView; static { //Load Dynamic library system.loadlibrary ("Testjni"); } @Override protected void onCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); TextView = (TextView) Findviewbyid (R.id.textview); Testjni Testjni = new Testjni (); Call the native method Boolean init = Testjni.init (); if (init = = true) { //Call the ADD function int sum = Testjni.add (+); Textview.settext ("You are really a" + sum); } else { Textview.settext ("You are 250 more than 250"); } Testjni.destory (); }}
Run the project as follows:
Follow the steps above to generate a. So file of your own, which can be called and executed correctly, and add two points here:
Note One: The NDK environment configuration:
1,:
Android NDK r10e:
32-bit: Http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86.exe
64-bit: Http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86_64.exe
Android NDK r9d:
32-bit: Https://dl.google.com/android/ndk/android-ndk-r9d-windows-x86.zip
64-bit: Https://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip
I use the ndk-r9d version, the above address needs to FQ, the corresponding version needs to leave the mailbox is good.
2, configure the PATH environment variable, cmd command line input ndk-build, appear the content prompt indicates the configuration is correct.
Android ndk:could not find application project directory! Android ndk:please define the Ndk_project_path variable to the it. d:\java\android-ndk-r9d\build/core/build-local.mk:148: * * * Android ndk:aborting . Stop.
Note two: Refer to the above article in the last input Ndk-build will prompt the following error:
At this point, modify the following in the Application.mk file:
App_project_path: = $ (call My-dir)/into App_project_path: = $ (call My-dir)/...
Article posted: http://www.cnblogs.com/sevenyuan/p/4202759.html
The JNI technology in the Android project generates and invokes the. So Dynamic library implementation