Java & JNI

Source: Internet
Author: User

[Sequence] I started to study JNI for the sake of Android research. Before reading this example, I hope you follow the previous article [Java] windows7
Environment variables have been correctly set.


This article uses a simple example to demonstrate how to use JNI. We write a Java program and use it to call a C function to print "Hello World !".

This process includes the following steps:

1. Create a class (helloworld. Java) to declare the local method.

2. Use javac to compile the source file hollowworld. Java and generate helloworld. Class. Use javah-JNI to generate the C header file (helloworld. h), which contains the function prototype of the local method.

3. Use C/C ++ code to write a function prototype.

4. Compile the C/C ++ function into a local library and generate libhelloworld. So.

5. Run the helloworld program using Java commands. The class file helloworld. Class and libhelloworld. So are loaded at runtime.

Now we follow the steps above to implement it step by step:

1. Create helloworld. Java

<strong>class HelloWorld{    private native void print();    public static void main(String[] args)    {        new HelloWorld().print();    }    static    {        System.loadLibrary("HelloWorld");    }}</strong>

Ii. Generate helloworld. Class and helloworld. h

1. Compile helloworld. Java to generate helloworld. Class

CD to the directory where helloworld. Java is located. Run the following command in the command line:

Javac helloworld. Java

Compile and generate helloworld. Class in the current folder.

2. Generate helloworld. h

Run:

Javah-JNI helloworld // remember javah instead of Java

The following error may be prompted:

Error: unable to access helloworld

Helloworld class file not found

The cause of the error is that the Java classpath does not contain the current path strength. There are two solutions:
Use the following command line instead
Javah-classpath $ PWD-JNI helloworld // where $ PWD is the current path, write the absolute path in win7
Or:

Export classpath = $ classpath: $ PWD; javah-JNI helloworld // command in Linux compiling environment

In this way, helloworld. h can be generated in the current directory. The content is as follows:

<strong>/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloWorld */#ifndef _Included_HelloWorld#define _Included_HelloWorld#ifdef __cplusplusextern "C" {#endif/* * Class:     HelloWorld * Method:    print * Signature: ()V */JNIEXPORT void JNICALL Java_HelloWorld_print  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif</strong>

This file contains a declaration of the java_helloworld_print function. Here there are two parameters, which are very important and will be discussed later.

Iii. Implementation of writing a function prototype using C/C ++ code

Create helloworld. cpp in the current directory. The content is as follows:

<Strong> # include <JNI. h> # include <stdio. h> # include "helloworld. H "jniexport void jnicall java_helloworld_print (jnienv * ENV, jobject OBJ) {printf (" Hello world! \ N ") ;}</strong>Note that the JNI. h header file must be included. This file defines various types and macro definitions used by JNI. The JNI header file is stored in your JDK installation path. For example, if my JDK is installed in the/usr/lib/JVM/Java-1.5.0-Sun Directory, then JNI. h exists in the/usr/lib/JVM/Java-1.5.0-sun/include directory, which will be used soon.


Function return type
Jstring indicates the return type. It should be a Java string.

JniexportJnicall indicates that the function is called by JNI.
Function Name
The function name is first prefixed with Java, and then the path of the Java class of JNI to be called, helloworld
Then the name of the function stated in Java. Print
Function Parameters
The first parameter should always be jnienv * ENV,
The second parameter jobject thiz is the this pointer in Java.
The third parameter starts with a parameter in the Java function.

In addition, pay attention to the two parameters of java_helloworld_print. This example is simple and does not require these two parameters. However, these two parameters are very important in JNI. Env represents the Java Virtual Machine environment. The parameters passed by Java are very different from those passed by C. You need to call the interface provided by JVM to convert it to the C/C ++ type, the env method is called to complete the conversion. OBJ indicates the called object, which is equivalent to this of C ++. When the C/C ++ function needs to change the member variable of the called object, this object can be operated.

4. Compile the C/C ++ function into a local library and generate libhelloworld. So

Run the following command on the terminal to generate libhelloworld. So:

G ++-I/usr/lib/JVM/Java-1.5.0-sun/include/Linux/-I/usr/lib/JVM/Java-1.5.0-sun/include /- FPIC-shared-O libhelloworld. so helloworld. CPP

Generate libhelloworld. So in the current directory. Note that the include directory of Java must be included (set according to your system environment), because helloworld. C contains JNI. h.

In helloworld. Java, the loadlibrary method loads "helloworld", but the library we generate is libhelloworld. This is what Linux links stipulate. A library must be lib + Library name +. So. You only need to provide the database name for the link.

5. Run the helloworld program using Java commands (the execution environment is Linux, and The. So is a dynamic library in Linux. Do not try to run it in Windows)

Enter and run the helloworld program in the terminal:

java HelloWorld
The following error may occur:

Exception in thread "Main" Java. Lang. noclassdeffounderror: helloworld

This error occurs because the classpath environment variable does not contain the current directory. The solution is the same as that mentioned above:

Java-classpath $ PWD helloworld

Or:

Export classpath = $ classpath: $ PWD; Java helloworld

The following error may also occur:

<Strong> exception in thread "Main" Java. lang. unsatisfiedlinkerror: No helloworld in Java. library. path <br/> at java. lang. classloader. loadlibrary (classloader. java: 1682) <br/> at java. lang. runtime. loadlibrary0 (runtime. java: 822) <br/> at java. lang. system. loadlibrary (system. java: 993) <br/> at helloworld. <clinit> (helloworld. java: 11) </strong>

The cause of this error is that the environment variable LD_LIBRARY_PATH does not contain the current directory, and the helloworld program cannot find the library libhelloworld. So. The solution is as follows:

Export LD_LIBRARY_PATH = $ LD_LIBRARY_PATH: $ PWD; export classpath = $ classpath: $ PWD; Java helloworld

In this way, we can see the expected results:

Hello world!

In fact, before we generate helloworld. H, we can first modify the LD_LIBRARY_PATH and classpath environment variables:

Export LD_LIBRARY_PATH = $ LD_LIBRARY_PATH: $ PWD; export classpath = $ classpath: $ pwd

To generate helloworld. H, you only need to run the command javah-JNI helloworld; To Run helloworld, you only need to run the command Java 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.