Java jni calls c function instance share of Java calls c function

  • 2020-04-01 02:37:49
  • OfStack

From C/C++ to Java, from Java back to C/C++, today finally had the opportunity to understand the bridge between Java, C/C++ - JNI. Ha ha! Share!

A list,
JNI is short for Java native interface, which translates to Java native interface. Java can call C/C++ libraries through JNI, which is a great way for Java programs that require a lot of performance or for tasks that Java can't handle.

Purpose: to invoke C/C++ code in Java code
Three, implementation: assume that our Java program for j2c.java, C program for j2c.c, the communication between Java and C function named write2proc;
                          So the declaration of write2proc is in j2c.java, and the implementation is in j2c.c;
Four, operations,
1. Write and compile Java programs

      Javac are. Java = > As the class
2. Generate C/C++ header files

      Javah as = > J2c.h ($PATH should be added to $JAVA_HOME after JDK installation, otherwise use an absolute PATH such as /usr/bin/javah)

3. Write the corresponding C/C++ program: j2c.c

4. Generate C/C++ object files
      Gcc-i /usr/lib/ JVM/java-6-openjdk-amd64/include-i /usr/lib/ JVM /java-6-openjdk-amd64/include/ linux-fpic-c j2c.c => As the o
5. Generate C/C++ Shared libraries

      Gcc-shared-wl,-soname,libj2c.so. 1-o libj2c.so.1.0 j2c.o => Libj2c. So. 1.0

6. Rename cp libj2c.so.1.0 libj2c.so => Libj2c. So

7. Add the Shared library to the path of the dynamically linked library (in this case, the current directory)
      Export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:.

8. Execute Java program to realize cross-language communication
        Java as

 

V. specific process

1. Write and compile j2c.java


import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
public class J2C
{ 
     static 
     { 
          try{ 
               //Here is the linked library name of the local method
               System.loadLibrary("j2c");
          } catch(UnsatisfiedLinkError e) 
          { 
               System.err.println( "Cannot load J2C library:n " + 
               e.toString() ); 
          } 
     }
     //Declared local methods
     public static native int write2proc(int pid);
     public static void main(String[] args){
          //Gets the pid of the process (that is, the main thread)
          final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
          final String info = runtime.getName();
          final int index = info.indexOf("@");

          if (index != -1) {
               final int pid = Integer.parseInt(info.substring(0, index));
               System.out.println(info);
               System.out.println(pid);
               write2proc(pid);
          }

          try{
               Thread.sleep(8000);
          } catch(InterruptedException e){
               e.printStackTrace();
          }
     }
}

Note: the parameter Name of system.loadlibrary in Java program refers to the Shared C/C++ library to be loaded. The Shared library Name generated in step 6 must be consistent with this parameter, that is, system.loadlibrary (Name) corresponds to the Shared library Name libname.so (the Shared library Name must start with lib).

2. Generate C header file j2c.h: javah J2C



#include <jni.h>

#ifndef _Included_J2C
#define _Included_J2C
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL Java_J2C_write2proc
     (JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif

The header file is generated automatically, do not modify it;

2. Function JNIEXPORT jint JNICALL Java_J2C_write2proc(JNIEnv *, jclass, jint);

  According to the annotation, it is defined in the class J2C method write2proc of j2c.java file, so the implementation function of C program must be consistent with the signature.

3. Write C program j2c.c


#include <stdio.h>
#include "J2C.h"
JNIEXPORT int JNICALL Java_J2C_write2proc(JNIEnv * env, jobject arg, jint pid) 
{
     printf("current pid is %dn", pid);
     return 0;
}

4. Compile C programs

Because the C program #include "j2c.h" and j2c.h #include < Jni. H> While the default environment in GCC does not know what jni.h is, so the compiler needs to be told the location of jni.h (jni.h is under $JAVA_HOME/include in JDK) at compile time, so the above compilation parameters are included.

Because the dynamic library is compiled using GCC, there are exceptions in some cases when jni is invoked, so try g++ instead.

conclusion

1. The Java method prototype declaration must be consistent with the corresponding C/C++ implementation file definition (can be compared by automatically generated C/C++ header file), especially the class name and method name;

2. The Shared library name loaded by system.loadlibrary () in Java must be the same as the Shared library name generated by C/C++.


Related articles: