Using JNI in linux to call JAVA classes in C/C ++

Source: Internet
Author: User
Original article address:Using JNI in linux to call JAVA classes in C/C ++ Author:Happy Man

Recently, I am working on a C/C ++ program to call java. The Calling method of java here is not exec (/path/to/java ,.....), instead, it calls a specific function in a class file.

 

The practice is summarized as follows:

 

1. Install jdk

2. Install gcc (you do not need to install it if it comes with linux)

 

Java native interface (JNI) is used to dynamically establish java runtime environment.

First, the C/C ++ program contains the header file "jni. h"

# Include <jni. h> is generally in the JAVA_HOME/include directory.

Call the method in jni. h to create the runtime env and then call the java program.

 

Second, compile

G ++-o testjava. cpp-I $ {JAVA_HOME}/include/linux-L $ {JRE_HOME}/lib/i386/client-ljvm

 

The above is the general idea. The detailed process is as follows:

 

######################################## ######################################## #####

1. install and configure the Java environment

My Linux is Redhat Enterprise Linux 5, kernel version 2.6.18
Installing Java in Linux is relatively simple. You can visit the Java download website or the free software library, and select all the operating system types you have installed (Linux, Linux amd64, Solaris, etc ). Once you have chosen to download an object-either a self-decompressed execution file or a self-decompressed RPM file, you can install it. I downloaded the jdk-1_5_0_06-linux-i586.bin:

# Mkdir/usr/local/java

# Cd/usr/local/java

# Cp/home/soft/jdk-1_5_0_06-linux-i586.bin ./

# Chmod u + x jdk-1_5_0_06-linux-i586.bin

#./Jdk-1_5_0_06-linux-i586.bin

After the jdk1.5.0 _ 06 directory is generated, JDK is installed in/usr/local/Java/jdk1.5.0 _ 06 /. Run the following code to get a test result:

# Cd jdk1.5.0 _ 06/bin

[Root @ localhost bin] #./java-version

Java version "1.5.0 _ 06"

Java (TM) 2 Runtime Environment, Standard Edition (build 1.5.0 _ 06-b05)

Java HotSpot (TM) Client VM (build 1.5.0 _ 06-b05, mixed mode, sharing)

  

To be able to use Java, you need to set the following environment variables:

JAVA_HOME =/usr/local/java/jdk1.5.0 _ 06

PATH = $ PATH:/usr/local/java/jre1.5.0 _ 05/bin

Export JAVA_HOME PATH

Export JRE_HOME =/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre

Export LD_LIBRARY_PATH = $ LD_LIBRARY_PATH: $ JRE_HOME/lib/i386: $ JRE_HOME/lib/i386/client

 

Note the jre_home configuration. If there is no JRE environment on the machine, install JRE. The installation method is similar to installing JDK.

After setting, you can view the variable value.

[Root @ localhost bin] # echo $ java_home

/Usr/local/Java/jdk1.5.0 _ 06

[Root @ localhost bin] # echo $ path

/Usr/Kerberos/sbin:/usr/Kerberos/bin:/usr/local/bin:/usr/bin:/home/zhangp/bin: /usr/lib/JVM/java-1.4.2-gcj-1.4.2.0/JRE/bin:/usr/local/Java/jdk1.5.0 _ 06/bin

 

2. Compile a simple Java program

 

Package com. test;

Public class mytest {
 Public mytest (){
  Super ();
 }

 Public static int add (int a, int B ){
  Return a + B;
 }

 Public boolean judge (boolean bool ){
   Return! Bool;
 }
}

Compile the Java program:

# Javac MyTest. java

Generate MyTest after compilation. class, which is placed in the com/test directory of the current directory. when calling the JNI of the C ++ program, the relevant methods will be used to find the class in the com/test directory.

 

C ++ Program

 

# Include <stdio. h>
# Include <iostream>
# Include <jni. h>
# Include <stdlib. h>
# Include <assert. h>

 

Jstring stoJstring (JNIEnv * env, const char * pat)
{
 Jclass strClass = env-> FindClass ("java/lang/String ");
 JmethodID ctorID = env-> GetMethodID (strClass, "<init>", "([BLjava/lang/String;) V ");
 JbyteArray bytes = env-> NewByteArray (strlen (pat ));
 Env-> SetByteArrayRegion (bytes, 0, strlen (pat), (jbyte *) pat );
 Jstring encoding = env-> NewStringUTF ("UTF-8 ");
 Return (jstring) env-> NewObject (strClass, ctorID, bytes, encoding );
}

 

Char * jstringTostring (JNIEnv * env, jstring jstr)
{
 Char * rtn = NULL;
 Jclass clsstring = env-> FindClass ("java/lang/String ");
 Jstring strencode = env-> newstringutf ("UTF-8 ");
 Jmethodid mid = env-> getmethodid (clsstring, "getbytes", "(ljava/lang/string;) [B ");
 Jbytearray Barr = (jbytearray) ENV-> callobjectmethod (jstr, mid, strencode );
 Jsize Alen = env-> getarraylength (Barr );
 Jbyte * Ba = env-> getbytearrayelements (Barr, jni_false );
 If (Alen> 0 ){
  RTN = (char *) malloc (Alen + 1 );
  Memcpy (RTN, Ba, Alen );
  RTN [Alen] = 0;
 }
 Env-> releasebytearrayelements(Barr, Ba, 0 );
 Return rtn;
}

 

Using namespace std;

 

Int main ()
{
 JavaVMOption options [2];
 JNIEnv * env;
 JavaVM * jvm;
 JavaVMInitArgs vm_args;
 Long status;
 Jclass cls;
 JmethodID mid;
 Jint square;
 Jboolean jnot;
 Jobject jobj;

 Options [0]. optionString = "-Djava. compiler = NONE ";
 Options [1]. optionString = "-Djava. class. path = .";
 // Options [2]. optionstring = "-verbose: JNI"; // used for tracking runtime information

 Vm_args.version = jni_version_1_4; // JDK version
 Vm_args.noptions = 2;
 Vm_args.options = options;
 Vm_args.ignoreunrecognized = jni_true;

 Status = jni_createjavavm (& JVM, (void **) & ENV, & vm_args );

 If (status! = Jni_err ){
  Printf ("create Java JVM successn ");
  CLS = env-> findclass ("com/test/mytest ");// Search for the Ava class here
  If (CLS! = 0 ){
   Printf ("find java class successn ");
   // Constructor
   Mid = env-> GetMethodID (cls, "<init>", "() V ");
   If (mid! = 0 ){
    Jobj = env-> NewObject (cls, mid );
    Std: cout <"init OK" <std: endl;
   }
       
   // Call the add function
   Mid = env-> GetStaticMethodID (cls, "add", "(II) I ");
   If (mid! = 0 ){
    Square = env-> CallStaticIntMethod (cls, mid, 5 );
    Std: cout <square <std: endl;
   }

   

   // Call the judge Function
   Mid = env-> getmethodid (CLS, "judge", "(z) z ");
   If (Mid! = 0 ){
    Jnot = env-> callbooleanmethod (jobj, mid, 1 );
    If (! Jnot) STD: cout <"Boolean OK" <STD: Endl;

   }
  }
  Else {
   Fprintf (stderr, "findclass failedn ");
  }
 
  JVM-> destroyjavavm ();
  Fprintf (stdout, "Java VM destory. N ");
  Return 0;
 }
 Else {
  Printf ("create Java JVM failn ");
  Return-1;
 }

}

 

Compile the C ++ Program (premise: the Java environment has been set up, that is, java_home, path, jre_home, LD_LIBRARY_PATH)
[Root @ localhost JNI] # G ++-O testjava. CPP-I $ {java_home}/include/Linux-L $ {jre_home}/lib/i386/client-ljvm

 

After compilation, you can use LDD testjava to check the correctness of the link library used by the SDK.

 

Run:
[Root @ localhost JNI] #./testjava
Create Java JVM success
Find Java class success
Init OK
10
Boolean OK
Java VM destory.

Set jre_home and LD_LIBRARY_PATH, and use libjvm under jre_home to compile the C ++ program. so dynamic library (I used the libjvm in the java_home directory I mentioned online at the beginning. so, the following error is returned.

# An Unexpected error has been detected by hotspot virtual machine:
#
#SIGSEGV (0xb) at PC = 0xb6d3dbe3, pid = 14454, tid = 2773482416
#
# Java VM: Java hotspot (TM) server VM (1.5.0 _ 11-b03 Mixed Mode)

.....

 

------ The end -----

######################################## ######################################## #####

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.