JNI from itwiki

Source: Internet
Author: User
JNI from itwiki

More JNI information can be found in the spec of JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html

Jump to: navigation, & lt; jumptosearch & gt;

JNI is short for Java Native Interface. Since Java 1.1, the Java Native Interface (JNI) standard has become part of the Java platform. It allows Java code to interact with code written in other languages. JNI was initially designed for locally compiled languages, especially C and C ++, but it does not prevent you from using other languages, as long as the call conventions are supported.

Using Java to interact with locally compiled code usually results in loss of platform portability. However, in some cases, this is acceptable or even necessary. For example, you can use old libraries to interact with hardware and operating systems, or to improve program performance. The JNI standard should at least ensure that local code can work under any Java Virtual Machine implementation.

I. design objective of JNI (Java Native Interface)

· The standard Java class library may not support
Platform-dependent features needed by your application.
· You may already have a library or application written in another
Programming Language and you wish to make it accessible to Java
Applications
· You may want to implement a small portion of time-critical code in
Lower-level programming language, such as assembly, and then have your
Java application call these functions

Ii. Writing steps of JNI (Java Native Interface)

· Compile a Java class with native declarations
· Use the javac command to compile the compiled Java class
· Use javah? JNI Java class names generate header files with the extension H
· Use C/C ++ to implement local methods
· Generate a dynamic connection library for files written in C/C ++
     ·ok

1) Compile a Java program:
The following uses helloworld as an example.
Code 1:
Class helloworld {
Public native void displayhelloworld ();

Static {
System. loadlibrary ("hello ");
}

Public static void main (string [] ARGs ){
New helloworld (). displayhelloworld ();
}
}
Declare native method: If you want to use a method as a local method, you must declare the method to native and cannot implement it. The parameters and return values of the method are following
Description.
Load dynamic library: system. loadlibrary ("hello"); load dynamic library (we can understand this as follows: Our Method
Displayhelloworld () is not implemented, but we use it directly below, so we must initialize it before use.) in this case, it is usually loaded using static blocks.
. Note that the parameter "hello" of system. loadlibrary (); is the name of the dynamic library.
Main () method
2) There is nothing to say about compilation.
Javac helloworld. Java
3) generate a header file with the extension of H
Javah? JNI helloworld
Header file content:
/* Do not edit this file-it is machine generated */

  1. Include

/* Header for class helloworld */

  1. Ifndef _ included_helloworld
  2. Define _ included_helloworld
  3. Ifdef _ cplusplus

Extern "C "{

  1. Endif

/*

  • Class: helloworld
  • Method: displayhelloworld
  • Signature: () V
  • /

Jniexport void jnicall java_helloworld_displayhelloworld
(Jnienv *, jobject );

  1. Ifdef _ cplusplus

}

  1. Endif
  2. Endif

(Here we can understand it as follows: This H file is equivalent to our interface in Java. Here we declare
Java_helloworld_displayhelloworld (jnienv *,
Jobject); method, and then implement this method in our local method, that is to say, the method name we use when writing C/C ++ programs must be the same as here ).
4) Compile local methods
Implement the same method as the method name declared in the header file generated by the javah command.
Code 2:
1 # include 2 # include "helloworld. H"
3 # include

4 jniexport void jnicall
Java_helloworld_displayhelloworld (jnienv * ENV, jobject OBJ ){
Printf ("Hello world! /N ");
Return;
}
Note that the 1st lines in Code 2 need to introduce the JNI. H (this file can be found under the % java_home %/include folder) file, because the jnienv,
Jobject and other types are defined in this header file. In addition, the header file helloworld. h needs to be introduced in line 1 (I understand this: it is equivalent to
To implement an interface, you need to declare it. here we will implement the methods declared in the header file helloworld. h. Of course not necessarily ). Save
Helloworldimpl. C is OK.
5) generate a dynamic library
Here, we use Windows as an example to generate a DLL file. Use the VC compiler Cl to save the helloworldimpl. c folder.
CL-I % java_home %/include/Win32-LD
Helloworldimp. C-fehello. dll
Note: The generated DLL file name is configured after option-Fe. Here is hello, because the name we use when loadlibary in the helloworld. Java File
The word is hello. Of course, after modification, it also needs to be modified. In addition, you need to set-I % java_home %/include
-Add the I % java_home %/include/Win32 parameter, because the JNI. H file is introduced when writing the local method in step 4.
6) run the program
Java helloworld is OK. Pai_^

Iii. Example of JNI (Java Native Interface)

The following is a simple example to implement the function of printing a sentence, but the printf of C is used for the final implementation. The JNI interface provided to Java generally includes a so file (which encapsulates the implementation of the c function) and a Java file (the class that needs to call the path ).
1. the purpose of JNI is to enable the Java method to call some functions implemented by C. For example, in the following Java class, a local function testjni (usually declared as private native) needs to be called ), first, create the weiqiong file. java, the content is as follows:

Class weiqiong
{
Static
{
System. loadlibrary ("testjni"); // load the static library, where the test function is implemented
}
Private native void testjni (); // declare a local call
Public void test ()
{
Testjni ();
}
Public static void main (string ARGs [])
{
Weiqiong Haha = new weiqiong ();
Haha. Test ();
}
}

2. Then run javac weiqiong. java. If no error is reported, a weiqiong. Class is generated.
3. Run javah weiqiong to generate a weiqiong. h file. The declaration of a function is as follows:

Jniexport void jnicall java_weiqiong_testjni
(Jnienv *, jobject );

4. Create the file testjni. C and implement the above function. The content is as follows:
  1. Include
  2. Include

Jniexport void jnicall java_weiqiong_testjni
(Jnienv * ENV, jobject OBJ)
{
Printf ("Haha --------- go into C !!! /N ");
}

5. to generate the. So file, create the MAKEFILE file as follows:

Libtestjni. So: testjni. O makefile
Gcc-wall-rdynamic-shared-O libtestjni. So testjni. o
Testjni. O: testjni. c weiqiong. h
Gcc-wall-C testjni. C-I./-I/usr/Java/j2sdk1.4.0/include-I/usr/Java/j2sdk1.4.0/include/Linux
CL:
Rm-RF *. O *. So
Note: The tab is blank before GCC. The j2sdk directory is written according to the specific version of j2sdk installed by yourself. The generated so file name must be "lib" before the parameter name of loadlibrary ".

6. Export LD_LIBRARY_PATH =., and set the library path to the current directory so that the so file can be found in the Java file. The general practice is to copy the so file to the local LD_LIBRARY_PATH directory.
7. execute Java weiqiong and print the result: "Haha --------- go into C !!!"

Iv. Issues in JNI (Java Native Interface) calls

I had some questions when I used JNI for the first time. Later I was able to solve these problems one by one. The following are my notes:
1. How is Java and C interconnected?
In fact, the main reason for the inability to communicate is the data type problem. JNI solves this problem. For example, the jstring data type in the C file is the string object passed in by Java, after the conversion of the JNI function, it can become the char * of C *.
The following table lists the corresponding data type relationships:

Java local C type description
Boolean jboolean unsigned, 8-bit
Byte jbyte unsigned, 8-bit
Char jchar unsigned, 16-bit
Short jshort signed, 16 bits
Int jint signed, 32-bit
Long jlong signed, 64-bit
Float jfloat 32-bit
Double jdouble 64-bit
Void void N/

JNI also contains many reference types corresponding to different Java objects, such:

2. How to convert the string parameter passed in by Java to the char * of C and then use it?

The string parameter passed in by Java is converted to the Data Type of jstring by JNI in the C file. Declare char * test in the C file, and then test =
(Char *) (* env)-> getstringutfchars (ENV, jstring,
Null); Note: after the test is used, you do not need to access the Code related to the VM platform: (* env)-> releasestringutfchars (ENV,
Jstring, test );

3. Pass the buffer of a char * obtained in C to Java?

If this char * is a general string, it can be returned as a string. If it is a buffer containing '/0', it is best to use bytearray for outgoing transmission, because the length of copy can be set. If it is copied to string, it may be truncated to'/0.

There are two ways to pass the data:
One is to directly create a byte array in JNI, and then call the function (* env)-> setbytearrayregion (ENV, bytearray, 0, Len, buffer ); copy the buffer value to bytearray, and the function can return bytearray directly.
One is the return error code. The data is transmitted as the parameter, but the basic data type of Java is to pass the value, and the object is to pass the reference, use a class package to package the byte array to be transmitted, as shown below:

Class retobj
{
Public byte [] bytearray;
}
This object is transmitted as the retobj parameter of the function. The following function is used to assign values to the byte array in retobj to facilitate the transfer. The Code is as follows:
Jclass CLS;
Jfieldid FID;
Jbytearray bytearray;
Bytearray = (* env)-> newbytearray (ENV, Len );
(* Env)-> setbytearrayregion (ENV, bytearray, 0, Len, buffer );
CLS = (* env)-> getobjectclass (ENV, retobj );
FID = (* env)-> getfieldid (ENV, CLS, "retbytes", "[B"]);
(* Env)-> setobjectfield (ENV, retobj, FID, bytearray );

4. I don't know how much buffer is occupied. How can I transfer it out?
In the jni c file, the new output space is passed out. If Java data is not initialized, point to the space passed out.

V. Processing of imported Java data in JNI

1. If bytearray is input, perform the following processing to obtain the buffer:

Char * tmpdata = (char *) (* env)-> getbytearrayelements (ENV, bytearray, null );
(* Env)-> releasebytearrayelements (ENV, bytearray, tmpdata, 0 );

(Source: crybaby2005.bokee.com; miniufo.bokee.com)

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.