Home > System Tutorial > LINUX > body text

How to use JNI to call C/C++ code under Linux

PHPz
Release: 2024-02-13 15:30:04
forward
1048 people have browsed it

Have you ever thought about using C or C features in a Java program? Do you know what JNI is and how it allows you to implement cross-language programming under Linux? If you are interested in these questions, then this article is for you. This article will introduce the basic concepts of JNI, as well as the steps and examples of how to use JNI to call C/C code under Linux.

How to use JNI to call C/C++ code under Linux

Define a Java class — Hello class

 public class Hello 
 { 
  static 
  { 
   try 
   { 
 // 此处即为本地方法所在链接库名
    System.loadLibrary("hello"); 
   } 
   catch(UnsatisfiedLinkError e) 
   { 
    System.err.println( "Cannot load hello library:\n " + 
                                e.toString() ); 
   } 
  } 
  public Hello() 
  { 
  } 
 // 声明的本地方法
   public native void SayHello(String strName); 
 }
Copy after login

There are two things to note here:

First: Write a native method declaration for each native method you want to use, except that the native keyword must be specified, as follows:

public native void SayHello(String strName);
Copy after login

Second: The local code library must be loaded explicitly. We need to load this library in the static block of the class (the static library will be called when the class is loaded)

Now we edit hello.java to generate hello.class file.

Generate local link library

To generate a Java local interface header file for the class defined above, you need to use javah. The javah function of the Java compiler will generate the necessary declarations based on the Hello class. This command will generate the Hello.h file

The content of the generated Hello.h file is as follows:

 #include  
 /* Header for class Hello */ 
 #ifndef _Included_Hello 
 #define _Included_Hello 
 #ifdef __cplusplus 
 extern "C" { 
 #endif 
 /* 
 * Class:     Hello 
 * Method:    SayHello 
 * Signature: (Ljava/lang/String;)V 
 */ 
 JNIEXPORT void JNICALL Java_Hello_SayHello 
  (JNIEnv *, jobject, jstring); 
 #ifdef __cplusplus 
 } 
 #endif 
 #endif
Copy after login

Create a CPP file Hello.cpp

in the same path as Hello.h

The content is as follows:

#include "Hello.h"
 #include  
 // 与 Hello.h 中函数声明相同
 JNIEXPORT void JNICALL Java_Hello_SayHello  (JNIEnv * env, jobject arg, jstring instring) 
 { 
   // 从 instring 字符串取得指向字符串 UTF 编码的指针
 const jbyte *str = 
        (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE ); 
    printf("Hello,%s\n",str); 
  // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。
    env->ReleaseStringUTFChars( instring, (const char *)str ); 
    return; 
 }
Copy after login

There are three parameters here. Let’s talk about the parameter usage:

(1) All JNI calls use pointers of type JNIEnv *. It is customary to define this variable as evn in the CPP file, which is the first parameter of any local method. The env pointer points to a function pointer table, and the functions in it can be directly accessed using the "->" operator in VC.
(2) jobject points to a handle to the Java object LocalFunction instantiated in this Java code, which is equivalent to the this pointer.
(3) The third parameter is the parameter passed in by the Java program in the local call. In this example, there is only one String parameter. For string parameters, because Java strings cannot be read directly in native code, they must be converted to C/C strings or Unicode.

Compile and generate shared libraries.

When using GCC, you must tell the compiler where to find the support file for this Java native method, and explicitly tell the compiler to generate position-independent code. In my environment, compile according to the following process:

gcc -I/home/jbuilder/jdk1.3.1/include 
    -I/home/jbuilder/jdk1.3.1/include/linux -fPIC -c Hello.c
Copy after login

Generate Hello.o

gcc -shared -Wl,-soname,libhello.so -o libhello.so Hello.o
Copy after login

Generate libhello.so (this is the file name format of the dynamic link library under Linux, just like the .dll file suffix under Windows)

Finally notify the dynamic linker of the path of this shared file.

export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
Copy after login

Write a simple Java program to test our native method

Save the following source code as A.java:

 import Hello; 
 import java.util.*; 
 public class A 
 { 
  public static void main(String argv[]) 
  { 
   A a = new A(); 
  } 
  public A() 
  { 
   Hello h = new Hello(); 
   // 调用本地方法
   h.SayHello("Hello world");    
  } 
 }
Copy after login

Use javac to compile A.java and generate A.class
Using java A just like executing a normal Java program, we will see Hello world appear on the screen.
Through this article, you should have a preliminary understanding of JNI and how to use JNI to call C/C code under Linux. JNI is a powerful and flexible tool that allows you to take advantage of C/C in a Java program, or take advantage of Java in a C/C program. Of course, JNI also has some shortcomings, such as performance loss, memory leaks, error handling, etc. Therefore, when using JNI, you need to pay attention to some details and specifications to ensure the correctness and security of the code. I hope this article can be helpful to you. If you have any questions or suggestions, please leave a message in the comment area.

The above is the detailed content of How to use JNI to call C/C++ code under Linux. For more information, please follow other related articles on the PHP Chinese website!

source:lxlinux.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!