JNI/NDK Development Guide (i)--JNI development process and HelloWorld

Source: Internet
Author: User
Tags macbook

Reprint Please specify source: http://blog.csdn.net/xyang81/article/details/41777471

The JNI name is the acronym for the first letter of the Java Native Interface (Java local interface) word, which refers to interfaces developed with C and C + +. Because JNI is part of the JVM specification , we can run the JNI program we write in any Java virtual machine that implements the JNI specification. At the same time, this feature allows us to reuse a lot of code that was written in C + + previously.


The development of the JNI program is limited by the system environment, because the code or module written out in C + + language relies on some library functions provided by the current operating system environment and is linked to the local library. and compiled binaries can only run in the context of a local operating system, because different operating system environments have their own local libraries and CPU instruction sets, and each platform differs from the standard C + + specification and standard library function implementations. This creates a Java program that uses the JNI interface, which is no longer as free as the previous cross-platform. If you want to implement a cross-platform, you must compile the local code under different operating system platforms for the corresponding dynamic library.


The JNI development process is mainly divided into the following 6 steps:

1. Writing Java source code

2. Compile the Java source code into a class byte code file

3, the Javah-jni command to generate. h header file (Javah is a command that comes with the JDK,-jni parameter represents a function that generates a JNI rule with a function declared by native in class)

4. Using local code to implement the function in the H header file

5. Compiling local code into a dynamic library (Windows:*.dll, Linux/unix:*.so, Mac OS X:*.jnilib)

6. Copy the dynamic library to Java.library.path Local Library search directory, and run Java program



Through the above introduction, I believe that the JNI and the development process has a holistic understanding, the following through a helloworld example, and then in-depth understanding of the various aspects of JNI development and considerations.

PS: My development environment for Mac OS X 10.10.1, Eclipse 3.8 (Juno), if it is developed under other operating systems, simply compile the local code into a dynamic library supported by the current operating system.

This case introduces the development process in a command-line manner, so that you will be more impressed with the JNI development process, and the following cases are developed using ECLIPSE+CDT.

First step, and create a new Helloworld.java source file

Package Com.study.jnilearn;public class HelloWorld {public static native string SayHello (string name);//1. Declaration This is a native letter Number, implemented by local code public static void Main (string[] args) {String text = SayHello ("Yangxin");//3. Call local function System.out.println (text);} static {system.loadlibrary ("HelloWorld");//2. Load the dynamic library that implements the native function, just write the name of the Dynamic Library}}
Step two, compile the. Java source file into a. class bytecode file using the Javac command

Note: HelloWorld is placed under the Com.study.jnilearn bag.

Javac src/com/study/jnilearn/helloworld.java-d./bin
-d means to put the compiled class file in the specified directory, where I put it in the bin directory with SRC peers

The third step, using the JAVAH-JNI command, generates the. h header file According to the class bytecode file (the-jni parameter is optional )

Javah-jni-classpath./bin-d./jni Com.study.jnilearn.HelloWorld

The. h header file that is generated by default is named: Com_study_jnilearn_helloworld.h (Package name + class name. h), or you can specify the name of the generated header file by using the-o parameter:

Javah-jni-classpath./bin-o HelloWorld.h Com.study.jnilearn.HelloWorld
Parameter description:

-classpath: Class search path, which means looking from the current bin directory

-D: Place the resulting header file in the current JNI directory

-O: Specifies the generated header file name, which is generated by default in the class full pathname (package name + class name. h)

Note:-D and-O can only use one of these parameters.


Fourth step, implement the function in the. h header file with native code.

Com_study_jnilearn_helloworld.h:

/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_study_jnilearn_hellowor LD */#ifndef _included_com_study_jnilearn_helloworld#define _included_com_study_jnilearn_helloworld#ifdef __ Cplusplusextern "C" {#endif */* Class:     com_study_jnilearn_helloworld * Method:    SayHello * Signature: (ljava/ lang/string;) ljava/lang/string; */jniexport jstring jnicall Java_com_study_jnilearn_helloworld_sayhello  (jnienv *, Jclass, jstring); #ifdef __ Cplusplus} #endif #endif

HELLOWORLD.C:

Helloworld.c#include "Com_study_jnilearn_helloworld.h" #ifdef __cplusplusextern "C" {#endif/* * Class:     com_ Study_jnilearn_helloworld * Method:    SayHello * Signature: (ljava/lang/string;) ljava/lang/string; */jniexport Jstring jnicall Java_com_study_jnilearn_helloworld_sayhello (jnienv *env, Jclass cls, jstring j_str) {const char *C_STR = N Ull;char buff[128] = {0};c_str = (*env)->getstringutfchars (env, J_STR, NULL), if (c_str = = null) {printf ("Out of memory . \ n "); return NULL;} (*env)->releasestringutfchars (env, J_STR, C_str);p rintf ("Java str:%s\n", c_str); sprintf (buff, "Hello%s", c_str); Return (*ENV)->newstringutf (env, buff);} #ifdef __cplusplus} #endif
fifth step, compile cost-C + + code to dynamic library file

Dynamic library file name naming rules:lib+ dynamic library filename + suffix (the operating system is different, the suffix name is not the same) such as:

Mac OS X:libhelloworld.jnilib

Windows:HelloWorld.dll (Lib prefix not required)

Linux/unix:libhelloworld.so

1> Mac OS X

Gcc-dynamiclib-o/users/yangxin/library/java/extensions/libhelloworld.jnilib jni/helloworld.c-framework javavm-i/ $JAVA _home/include-i/$JAVA _home/include/darwin
My $java_home directory is in:/library/java/javavirtualmachines/jdk1.7.0_21.jdk/contents/home
Parameter Options Description:

-dynamiclib: means compiling into a dynamic-link library

-O: Specifies the path and file name generated by the dynamic-link library after compilation

-framework javavm-i: Compiling JNI requires the JVM's header file (jni.h), the first directory is platform independent, and the second directory is the header file associated with the operating system platform

2> Windows (Take Windows7 under VS2012 as an example)

Start menu-All Programs-->microsoft Visual Studio 2012--> open VS2012 X64 Native Tools command prompt, compile into DLL dynamic library with cl command:

Parameter Options Description:

-I: Like Mac OS X, contains the necessary header files for compiling JNI

-LD: Identity compiles the specified file into a dynamic-link library

-FE: Specifies the path and file name of the dynamic link library generated after compilation



3> Linux/unix

gcc-i$java_home/include-i$java_home/include/linux-fpic-shared Helloworld.c-o libHelloWorld.so
parameter Description:

-I: Contains the necessary header files for compiling JNI

-fpic: Compiling independent code that is location independent

-shared: Compiling into a dynamic library

-O: Specifies the path and file name generated by the post-compilation dynamic library


Sixth step, run Java program

Java needs to load the dynamic library before calling the native (local) method. If the native method is called before the dynamic is loaded, an exception is thrown that cannot find the dynamic link library file. As shown below:

Exception in thread "main" Java.lang.UnsatisfiedLinkError:com.study.jnilearn.HelloWorld.sayHello (ljava/lang/string ;) Ljava/lang/string;at Com.study.jnilearn.HelloWorld.sayHello (Native Method) at Com.study.jnilearn.HelloWorld.main (Helloworld.java:9)

It is generally most appropriate to load a dynamic library in a static (static) code block of a class, because when an instance of the class is created, the class is loaded into the virtual machine by ClassLoader and then immediately calls the static static code block of the class. It is foolproof to call the native method again. There are two ways to load a dynamic library:

System.loadlibrary ("HelloWorld"); System.load ("/users/yangxin/desktop/libhelloworld.jnilib");
Mode 1: Only need to specify the name of the dynamic library, do not need to add the Lib prefix, do not add. So,. dll, and. Jnilib suffixes

Method 2: Specify the absolute path name of the dynamic library, prefix and suffix required

If used 1,java will go to Java.library.path system properties to find the dynamic library file under the specified directory, if not found will throw the Java.lang.UnsatisfiedLinkError exception.

Exception in thread "main" Java.lang.UnsatisfiedLinkError:no HelloWorld2 in Java.library.pathat Java.lang.ClassLoader.loadLibrary (classloader.java:1860) at Java.lang.Runtime.loadLibrary0 (runtime.java:845) at Java.lang.System.loadLibrary (system.java:1084) at com.study.jnilearn.helloworld.<clinit> (Helloworld.java : 13)
as you can see from the anomaly, He is in the Java.library.path to find the name corresponding to the dynamic library, if you look under the Mac Libhelloworld.jnilib file, Linux under the libhelloworld.so file, Windows find LibHelloWorld.dll file, you can By calling the System.getproperties ("Java.library.path") method to get a list of directories to find, here is the lookup directory under my native Mac OS X system:

String librarydirs = system.getproperties ("Java.library.path"); System.out.println (librarydirs);//output results are as follows:/users/yangxin/library/java/extensions:/library/java/extensions:/ Network/library/java/extensions:/system/library/java/extensions:/usr/lib/java:.
There are two ways to get Java from Java.library.path to find dynamic link library files, you should have thought of the smart.

Method 1: Copy the dynamic link library to the Java.library.path directory

Method 2: Add the-djava.library.path= dynamic link Library Search directory parameter to the JVM, specifying the value of the system attribute Java.library.path

Java-djava.library.path=/users/yangxin/desktop


So much effort, finally can run the written Java program, the result is as follows:

Yangxin-macbook-pro:jnilearn yangxin$ java-classpath./bin Com.study.jnilearn.HelloWorldJava Str:yangxinhello Yangxin

Or

Yangxin-macbook-pro:jnilearn yangxin$ Java-djava.library.path=/users/yangxin/desktop-classpath./bin Com.study.jnilearn.HelloWorldJava Str:yangxinhello Yangxin


JNI/NDK Development Guide (i)--JNI development process and HelloWorld

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.