Home >Java >javaTutorial >Detailed explanation of the methods used by Java local interface JNI
This article mainly introduces relevant information on how to use Java local interface JNI in detail. I hope that through this article you can thoroughly use JNI programming. Friends in need can refer to
Detailed explanation of Java local interface JNI How to use
For Java programmers, I don’t think I need to explain the benefits and advantages of the Java language. Everyone will naturally tell you many things. But although we, as Java programmers, we have to admit that the Java language also has some shortcomings of its own. For example, it has its shortcomings in terms of performance and dealing with the underlying layer. Therefore, java provides some local interfaces. Its main function is to provide a standard way for java programs to interact with native code through the virtual machine. This is what we usually call java native interface (JNI - java native interface). . It enables Java code running inside the Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages such as C, C++, and assembly language. The most important benefit of JNI is that it imposes no restrictions on the implementation of the underlying Java virtual machine. Therefore, Java virtual machine vendors can add support for JNI without affecting other parts of the virtual machine. Programmers only need to write one version of a native application or library that will work with all JNI-enabled Java virtual machines. Let’s take a look at why you should interact with native code:
1: Improve application performance. We know that java is relatively "advanced" compared to c/c++ and assembly language. In fact, the advanced here is to simplify the programmer's work. Many low-level things are done by the Java virtual machine. But after all, compared to directly accessing the bottom layer, Java has one more step of the virtual machine process, so its performance is slightly slower than these native languages.
2: Implement some underlying-related functions. The standard class library and powerful API provided by the Java platform can complete most functions. However, some functions that deal with the underlying hardware cannot be completed in the class library provided by the Java API.
Three: Integrate with existing programs written in native code. When integrating software written in native languages such as c or c++ on the operating system, JNI can be used.
JNI interface functions and pointers
Platform-related code accesses Java virtual machine functions by calling JNI functions. JNI functions are available through interface pointers. An interface pointer is a pointer to a pointer, which points to an array of pointers, and each element in the array of pointers points to an interface function. Each interface function is located at a predetermined offset in the array. The following figure illustrates the organization of interface pointers.
The benefit of using interface tables instead of hard-coded function tables is to keep the JNI namespace separate from platform-specific code. A virtual machine can easily provide multiple versions of a JNI function table. For example, a virtual machine can support the following two JNI function tables:
· One table provides comprehensive checking of illegal parameters and is suitable for debugging programs;
· The other table Only the minimum level of checks required by the JNI specification is performed, so it is more efficient.
JNI interface pointer is only valid in the current thread. Therefore, native methods cannot pass interface pointers from one thread to another. A virtual machine that implements JNI can allocate and store local thread data in the area pointed to by the JNI interface pointer.
Native methods accept JNI interface pointers as parameters.
When the virtual machine makes multiple calls to a local method from the same Java thread, it ensures that the interface pointer passed to the local method is the same. However, a native method can be called by different Java threads and therefore can accept different JNI interface pointers.# (1) Write the Java class code
. In this class, use System. The 1oadLibrary() method loads the required dynamic link library. The key code is as follows://Compute.java public class Compute{ public native double sqrt(double params); static{ //调用动态链接库 System.loadLibrary(“compute”); }
(2) Compiled into byte code
(3) Generate header files for related JNI methods
这个过程的实现一般是通过利用jlavah-jni * class生成的(-jni可以省略),也可以手工生成该文件;但是由于 Java 虚拟机是根据一定的命名规范完成对JNI方法的调用,所以手工编写头文件需要特别小心。
上述文件产生的头文件部分代码如下:
//Compute.h extern“C”{ JNIEXPORT jdoubleJNICALL Java_Compute_comp(JNI-Env *, jobject, jdoubleArray);
JNI函数名称分为三部分:首先是Java关键字,供Java虚拟机识别;然后是调用者类名称(全限定的类名,其中用下划线代替名称分隔符);最后是对应的方法名称,各段名称之间用下划线分割。
JNI函数的参数也由三部分组成:首先是JNIEnv *,是一个指向JNI运行环境的指针;第二个参数随本地方法是静态还是非静态而有所不同一一非静态本地方法的第二个参数是对对象的引用,而静态本地方法的第二个参数是对其Java类的引用;其余的参数对应通常Java方法的参数,参数类型需要根据一定规则进行映射。
(4)编写相应方法的实现代码
在编码过程中,需要注意变量的长度问题,例如Java的整型变量长度为32位,而C语言为16位,所以要仔细核对变量类型映射表,防止在传值过程中出现问题。
(5)将JNI实现代码编译成动态链接库
编译过程是利用C/C++编译器实现的,在windows平台上,编译和连接的结果是动态链接库DLL文件。当要使用生成的动态链接库时,调用者类中需要显式调用该链接库dll文件。
经过上述处理,基本上完成了一个包含本地化方法的Java类的开发。
附录:将Jav类型映射到本地 C 类型
基本类型和本地等效类型 | ||
Java 类型 |
本地类型 |
说明 |
boolean |
jboolean |
无符号,8 位 |
byte |
jbyte |
无符号,8 位 |
char |
jchar |
无符号,16 位 |
short |
jshort |
有符号,16 位 |
int |
jint |
有符号,32 位 |
long |
jlong |
有符号,64 位 |
float |
jfloat |
32 位 |
double |
jdouble |
64 位 |
void |
void |
N/A |
为了使用方便,特提供以下定义。
#define JNI_FALSE 0 #define JNI_TRUE 1
jsize 整数类型用于描述主要指数和大小:
typedef jint jsize;
故障排除
当使用 JNI 从 Java 程序访问本机代码时,您会遇到许多问题。您会遇到的三个最常见的错误是:
1)无法找到动态链接。它所产生的错误消息是:java.lang.UnsatisfiedLinkError。这通常指无法找到共享库,或者无法找到共享库内特定的本机方法。
2)无法找到共享库文件。当用 System.loadLibrary(String libname) 方法(参数是文件名)装入库文件时,请确保文件名拼写正确以及没有指定扩展名。还有,确保库文件的位置在类路径中,从而确保 JVM 可以访问该库文件。
3)无法找到具有指定说明的方法。确保您的 C/C++ 函数实现拥有与头文件中的函数说明相同的说明。
结束语
从 Java 调用 C 或 C++ 本机代码(虽然不简单)是 Java 平台中一种良好集成的功能。虽然 JNI 支持 C 和 C++,但 C++ 接口更清晰一些并且通常比 C 接口更可取。正如您已经看到的,调用 C 或 C++ 本机代码需要赋予函数特殊的名称,并创建共享库文件。当利用现有代码库时,更改代码通常是不可取的。要避免这一点,在 C++ 中,通常创建代理代码或代理类,它们有专门的 JNI 所需的命名函数。然后,这些函数可以调用底层库函数,这些库函数的说明和实现保持不变。
The above is the detailed content of Detailed explanation of the methods used by Java local interface JNI. For more information, please follow other related articles on the PHP Chinese website!