There are several steps to writing JNI under Linux:
1. Write the Java source code that conforms to JNI
If the code contains Java local method, there is load dynamic link library system.loadlibrary ("Hello"), the other hello.o after the O can not write
2. Run Javac Generate class file
3. Run Javah to generate C header file
4. Write the source file of C + + according to the header file
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: GCC is in front of the tab empty, J2SDK directory according to their own J2SDK specific version to write, the resulting file must be the name of the LoadLibrary parameter name plus "Lib".
Run make command to generate. O and. So files
6. Copy the generated. So file to/root/test/env/lib (environment variable ld_library_path the dynamic library search path specified), and set the environment variable if it is not created by itself:
Export Ld_library_path=/root/test/env/lib, and copy the just generated. So file to the/root/test/env/lib path: CP libtestjni.so/root/test/env/lib
7. Run Java class name to produce results
Program POS output results using dynamic library corresponding to the dynamic library search path Specify the way
././libpos.so The Dynamic library search path specified when compiling the target code
/root/test/env/lib/root/test/env/lib/libpos.so environment variable ld_library_path specified dynamic library search path
/root/test/conf/lib/root/test/conf/lib/libpos.so The dynamic library search path specified in the/etc/ld.so.conf configuration file
/lib/lib/libpos.so The default dynamic library search path/lib
/usr/lib/usr/lib/libpos.so The default dynamic library search path/usr/lib
Jni
From Itwiki, the Open Information technology Encyclopedia
Jump To:navigation, <jumptoSearch>
JNI is the abbreviation of Java Native interface. Starting with Java 1.1, the Java Native Interface (JNI) standard is part of the Java platform, allowing Java code to interact with code written in other languages. JNI was first designed for locally compiled languages, especially C and C + +, but it does not prevent you from using other languages, as long as the calling convention is supported.
Using Java to interact with locally compiled code typically loses platform portability. However, in some cases this is acceptable and even necessary, such as using some old libraries, interacting with hardware, operating systems, or improving program performance. The JNI standard ensures that local code can work at least under any Java Virtual machine implementation.
The design purpose of JNI (Java Native Interface)
· The standard Java class library may isn't support the platform-dependent features needed by your application.
· You could already have a library or application written in another programming language and your wish to make it accessible t o Java Applications
· You could want to implement a small portion of time-critical code in a Lower-level programming language, such as assembly, a nd then have your Java application call all these functions
Ii. The writing steps of JNI (Java Native Interface)
• Java classes that write methods with native declarations
• Compile the Java class written using the Javac command
• Generate a header file with an extension of H using the Javah. JNI Java class name
• Implement a Local method using C + +
• Generate a dynamic connection library of files written by C/C + +
OK
1 Write Java program: Here take HelloWorld for example. Code 1:class HelloWorld {public native void Displayhelloworld ();
static {system.loadlibrary ("Hello");}
public static void Main (string[] args) {new HelloWorld (). Displayhelloworld ();}} Declaration Native method: If you want to use a method as a local method, then you must declare that the change method is native and cannot be implemented. The parameters and return values of the method are described later. Load Dynamic Library: system.loadlibrary ("Hello"); Load dynamic Library (we can understand this: our method Displayhelloworld () is not implemented, but we use it directly below, So you have to initialize it before you use it. This is typically loaded with a static block. Also note that the system.loadlibrary () parameter "Hello" is the name of the dynamic library. Main () Method 2 Compile there's nothing to say. Javac Helloworld.java 3) Generate header file with extension H javah. jni HelloWorld Header File contents:/* 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 this: This H file is equivalent to our interface in Java, where we declare a java_helloworld_displayhelloworld (JNIENV *, jobject); And then implement this method in our local approach, which means that the method name we use when writing C + + programs must be the same as here. 4 Write local method implementations and the same method names 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"); Note the 1th line in code 2, which requires that the jni.h (which can be found under the%java_home%/include folder) be introduced, because the types of jnienv, Jobject, and so on in the program are defined in the header file. And in line 2nd you need to introduce the HelloWorld.h header file (which I understand: the equivalent of when we're writing a Java program, we need to make a declaration to implement an interface, and here's the way to implement the HelloWorld.h header file declaration.) Not necessarily, of course. And then save it for helloworldimpl.c OK. 5 Generate dynamic libraries here for example in Windows, you need to generate DLL files. Under Save the HELLOWORLDIMPL.C folder, use the VC compiler CL. Cl-i%java_home%/include-i%java_home%/include/win32-ld Helloworldimp.c-fehello.dll Note: The generated DLL file name is configured after the option-fe, Here is hello, because the name we used when we loadlibary in the Helloworld.java file is hello. Of course, there are changes to be done here. Additional-i%java_home%/include-i%java_home%/include/win32 parameters need to be added because the jni.h file was introduced when the local method was written in step fourth. 6 Run the program Java HelloWorld on OK. ^_^
Summary use examples of JNI (Java Native Interface)
The following is a simple example to achieve the function of printing a sentence, but with the C of printf final implementation. The JNI interface typically provided to Java includes an so file (which encapsulates the implementation of the C function) and a Java file (a class that needs to call path).
1. The goal of JNI is to make it possible to invoke some functions of the C implementation, such as the following Java class, to invoke a local function testjni (generally declared private native type), first you need to create a file Weiqiong.java, which reads as follows:
Class Weiqiong {static {system.loadlibrary ("Testjni");/load a static library in which the test function implements} private native void Testjni ();//declare local call publ IC void Test () {Testjni ();} public static void Main (String args[]) {weiqiong haha = new Weiqiong (); Haha.test ();}}
2. Then execute Javac weiqiong.java, and if there is no error, a weiqiong.class will be generated.
3. Then executing Javah weiqiong, a file Weiqiong.h file is generated, with a function declared as follows:
Jniexport void Jnicall Java_weiqiong_testjni (jnienv *, jobject);
4. Create the file Testjni.c to implement the above function, which reads 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 GC C-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: gcc front Is the tab empty, J2SDK directory according to their own J2SDK specific version to write, the generated so file name must be LoadLibrary parameter name before adding "Lib".
6. Export Ld_library_path=., this sets the LIBRARY path to the current directory so that the Java file can find the so file. It is common practice to copy so files to the Ld_library_path directory of this machine.
7. Execute Java weiqiong, print out the result: "Haha---------go into c!!!"
Four Problems considered in JNI (Java Native Interface) calls
There are some questions when using JNI for the first time, and then one by one in use, and here is the memo for these questions:
1. How Java and C are interoperable.
In fact, the main reason for interoperability is the data type problem, JNI solved the problem, such as the C file jstring data type is a Java incoming string object, after the transformation of the JNI function can become the char* of C.
The corresponding data types relate to the following table:
Java type native C type description boolean Jboolean unsigned, 8-bit byte jbyte unsigned, 8-bit char Jchar unsigned, 16-bit short Jshort signed, 16-bit int jint signed, 32-bit L Ong Jlong signed, 64-bit float Jfloat 32-bit double jdouble 64-bit void void N/A
JNI also contains a number of reference types corresponding to different Java objects, as shown in the following illustration:
2. How do I convert Java incoming string argument to char* of C and use?
The string parameter that is passed in Java, converted to jstring data type in c file, declared char* test in C file, and then test = (char*) (*env)->getstringutfchars (env, Jstring, NULL) Note: When Test is finished, notify the virtual machine platform that the code does not need to be accessed again: (*env)->releasestringutfchars (env, jstring, test);
3. Pass the buffer of a char* obtained in C to Java.
If this char* is a generic string, it can be passed back as a string. If it contains a '/0 ' buffer, it is best to bytearray out as a copy of length, if copy to string, possibly to '/0 ' truncated.
There are two ways to pass the resulting data:
One is to directly new in JNI a byte array, and then call the function (*env)->setbytearrayregion (env, ByteArray, 0, Len, buffer); Copy the value of the buffer to the ByteArray , the function directly return ByteArray on it.
One is the return error number, the data is passed as a parameter, but the basic data type of Java is the pass value, the object is the passing reference, so the byte array that needs to be outgoing is wrapped in a class, as follows:
Class Retobj {public byte[] ByteArray} This object is passed as a parameter retobj of a function, assigning a byte array in retobj to be easily outgoing by using the following function. Code 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. Do not know how much space to occupy the buffer, how to pass out it.
New space in the C file of JNI, pass out. Java data is not initialized, pointing to the space to pass out.
Five The processing of Java incoming data in JNI
1. If the incoming is ByteArray, the following processing gets the buffer:
Char *tmpdata = (char*) (*env)->getbytearrayelements (env, ByteArray, NULL); (*env)->releasebytearrayelements (env, ByteArray, Tmpdata, 0);
(Source: crybaby2005.bokee.com;miniufo.bokee.com)