Java accesses the underlying operating system

native method definition:

 
 简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。

The role of native:

native主要用于方法上

1、一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现

2、在定义一个native方法时,并不提供实现体(比较像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的

主要是因为JAVA无法对操作系统底层进行操作,但是可以通过jni(java native interface)调用其他语言来实现底层的访问

How does VM make Native Method run:

 我们知道,当一个类第一次被使用到时,这个类的字节码会被加载到内存,并且只会回载一次。在这个被加载的字节码的入口维持着一个该类所有方法描述符的list,这些方法描述符包含这样一些信息:方法代码存于何处,它有哪些参数,方法的描述符(public之类)等等。
    如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针。这些实现在一些DLL文件内,但是它们会被操作系统加载到java程序的地址空间。当一个带有本地方法的类被加载时,其相关的DLL并未被加载,因此指向方法实现的指针并不会被设置。当本地方法被调用之前,这些DLL才会被加载,这是通过调用java.system.loadLibrary()实现的。

1. Overview
When looking at Java multi-threaded programming today, I found that there are multiple native methods in the Thread class. I have never seen this method before, so I am curious about it, and I have consulted some information. Now I will sort it out for preparation. forget.

1.1.native keyword usage
native is used in joint development with C++! Use the native keyword to indicate that this method is a native function, that is, this method is implemented in C/C++ language, and is compiled into a DLL, which is called by java. The implementation body of these functions is in the DLL, which is not included in the source code of the JDK, so you should not be able to see it. They are also different for different platforms. This is also the underlying mechanism of java. In fact, java calls different native methods on different platforms to access the operating system. all in all:

Native is used for cooperation between java and other languages ​​(such as c++), that is, the implementation of functions after native is not written in java.
Since it's not java, don't worry about its source code, we just need to know that this method has been implemented.
Native means to notify the operating system that you must implement this function for me, because I want to use it. Therefore, the functions of the native keyword are all implemented by the operating system, and java can only be called.
Java is a cross-platform language. Since it is cross-platform, the price paid is to sacrifice some control over the bottom layer. To achieve control over the bottom layer, Java needs the help of some other languages. This is the role of native

1.2 Introduction to JNI
The native method is implemented through JNI in java. JNI is the abbreviation of Java Native Interface. Since Java 1.1, the Java Native Interface (JNI) standard has been part of the Java platform, which allows Java code to interact with code written in other languages. JNI was originally designed for native compiled languages, especially C and C++, but it doesn't prevent you from using other languages ​​as long as the calling convention is supported. Using java to interact with natively compiled code often results in a loss of platform portability. However, there are some cases where it is acceptable or even necessary, for example, to use some old libraries, to interact with hardware, operating system, or to improve the performance of the program. The JNI standard at least guarantees that native code can work under any Java virtual machine implementation.
At present, there are three main technologies for interaction between java and dll: jni, jawin and jacob. Jni (Java Native Interface) is a technology provided by sun to interact between java and the native method in the system (in the windows\Linux system, it realizes the intermodulation between java and native method). Currently it can only be implemented by c/c++. The latter two are both open source projects on sourceforge, and both are application libraries on the windows system based on jni technology. Jacob (Java-Com Bridge) provides the ability for java programs to call methods in microsoft's com objects. In addition to the com object, jawin (Java/Win32 integration project) can also use methods in the win32-dll dynamic link library. In terms of function: jni >> jawin>jacob, its general structure is as follows:

As far as ease of use is concerned, the opposite is true: jacob>jawin>>jni.
While Jvm encapsulates the actual differences of various operating systems, it also provides jni technology, enabling developers to call library functions implemented by operating system-related technologies through java programs (codes), thereby interacting with other technologies and systems. The functions of the system implemented by other technologies; at the same time, other technologies and systems can also use the corresponding native interfaces provided by jni to call the internal functions of the java application system.

On the Windows system, generally executable applications are based on the native PE structure, and the jvm on Windows is also based on the native structure. The Java application system is built on top of the jvm.

For the application itself, Jni can be regarded as a proxy mode. For developers, it is necessary to use c/c++ to implement an agent program (jni program) to actually operate the target native function. In the java program, the jvm indirectly calls the target native function by loading and calling the jni program.

1.3JN writing steps
Write a java class with a native declared method and generate a .java file
Use the javac command to compile the written java class and generate a .class file
Use javah -jni java class name to generate a header file with an extension of h, That is, generate .h files
Use C/C++ (or other programming languages) to implement local methods, create .h file implementations, that is, create .cpp files to implement methods in .h files, and generate dynamic files written in C/C
++ Link library to generate dll file

2. JNI example
The following is that all operations are carried out under the directory: D:\JNI, the advantage of this is that it is easy to control. Another requirement is that our java class does not contain a package name. Currently, I only test successfully for types that do not contain a package name.
2.1. Write a java class with a native declared method: HelloWorld.java
public class HelloWorld { public native void displayHelloWorld();//java native method declaration

static {  
    System.loadLibrary("HelloWorldImpl");// 装入动态链接库,"HelloWorldImpl"是要装入的动态链接库名称。  
}  

public static void main(String[] args) {  
    // TODO Auto-generated method stub  
    HelloWorld helloWorld = new HelloWorld();  
    helloWorld.displayHelloWorld();  
}  

}
2.2. Use the javac command to compile the written java class
d:\JNI>javac HelloWorld.java
After executing the above command, generate D:\JNI\HelloWorld.class file
2.3. Use javah -jni java class name to generate the extension name h The header file
d:\JNI>javah -jni HelloWorld
generates the D:\JNI\HelloWorld.h file after executing the above command, and the content of the file is as follows:
/* DO NOT EDIT THIS FILE - it is machine generated /
#include <jni .h>
/
Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern “C” {
#endif
/*

  • Class: HelloWorld
  • Method: displayHelloWorld
  • Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
    (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
Here we can understand this: this h file is equivalent to our interface in java, here declares a Java_HelloWorld_displayHelloWorld (JNIEnv , jobject); method, and then implements this method in our local method, That is to say, the method name we use when writing C/C++ programs must be the same as here
2.4. Using C/C++ to implement local methods
Create HelloWorldImpl.cpp, the code is as follows:
#include “HelloWorld.h”
#include <stdio.h>
#include <jni.h>
/

  • Class: HelloWorld
  • Method: displayHelloWorld
  • Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
    (JNIEnv *, jobject)
    { printf("Hello World!\n"); return; } 3.5. Generate a dynamic link library from a file written in C/C++ and convert it to D:\Program Files\Java\jdk1.6.0_26\include\jni.h and D:\Program Files\Java\jdk1.6.0_26\include\win32\jni_md.h are copied to the D:\JNI\ directory. It is in the same directory as HelloWorldImpl.cpp, and the directory structure is shown in the figure below:




2.7 Execute cl/LD D:\JNI\HelloWorldImpl.cpp to get the HelloWorldImpl.dll file.
I am using visual studio 2010. To use the cl command, you must open the visual studio command line, as shown in the following figure:

Then enter the following command
cl/LD D:\JNI\HelloWorldImpl.cpp in the command line
, as shown in the figure below:

After executing the above command, we can see four generated files in C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC, which are: HelloWorldImpl.dll
HelloWorldImpl.exp
HelloWorldImpl.lib
HelloWorldImpl.obj
among
them Copy HelloWorldImpl.dll to the D:\JNI\ directory.
2.8. Execute the class to get the result
Run in cmd:
d:\JNI>java HelloWorld
as shown in the figure below:

3. Run under eclipse
4.1 Create a project called jnitest under eclipse
4.2 Add a HelloWorld.java same as 3.1
4.3 After saving HelloWorld.java, HelloWorld.class will be generated in the jnitest\bin directory.
4.4 Generate HelloWorld.h file according to HelloWorld.class
4.5 Create HelloWorldImpl.cpp to implement the method in HelloWorld.h
4.6 Use Visual studio 2010 to generate HelloWorldImpl.dll
4.7 Run the HelloWorld program in Eclipse, the error is reported as follows:
java.lang.UnsatisfiedLinkError: no HelloWorldImpl in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java :1028)
at HelloWorld.(HelloWorld.java:6)
4.8 Copy HelloWorldImpl.dll to C:\Windows\System32
4.9 Execute the HelloWorld program again, the program runs normally, and the console outputs "Hello World!"

What is JNI?
The full name of JNI is Java Native Interface. Java programs call methods written in non-java languages ​​by calling JNI. JNI supports the running of Java on different platforms. As long as the operating system is equipped with a dll file that stores JNI locally, Java programs can call JNI.
Generally, JNI is written by C and C++. Because C is a procedural language, it is more suitable for the underlying logic of the computer. In the same time and with the same function, the execution speed of JNI is faster than that of Java language. In order to achieve Java platform independence, JNI has different versions corresponding to different systems, so that java does not need to consider the local operating system when executing java, but uses different ddls to match different operating systems. For this reason, JDK does not DDL files are not included, and DDL files are stored in the ddl folder of the operating system. In the Windows 32-bit operating system, this path is C:\Windows\System32. In the Windows 64-bit system, the storage path of ddl is C:\Windows\SysWOW64 and C:\Windows\System32.

The loading of JNI
is well known. The loading of java methods is to load the bytecode into the java virtual space. The entry of the loaded bytecode maintains a list of all methods of the class. On this list, this method is recorded. The code storage location, parameters and method descriptors, when calling a certain method, java can find the code storage address by looking up this List, and then run it.
If a method descriptor has the word native, it will not store the address in this list, but store a pointer. When the program calls the relevant native method, it will find the corresponding dll file through the pointer, and load the dll file into the virtual machine. If the dll file is not found, a system error of no dll file will pop out. The dll file is loaded through the system loadLibrary() or load() method. The difference between these two methods is that when loadLibrary() is loaded, it will first look for dependency.dll, and when loading, you need to manually put the dependency.dll file into java .library.path in the path.

The method of loading dll
There are currently three ways to load dll in the java function library, namely JNI, Jawin and Jacob. The latter two are based on the technology developed by JNI, and Jacob implements the method of loading the com class library in Microsoft.

Operation steps of the Native method
Declare the Native() method in Java and compile it.
Generate a .h file in javah
Based on the dll file, use the .cpp file to implement the native export method
Compile the cpp file to generate a dynamic link library file Use
the System.loadLibrary() method to load the dynamic link library file in Java, and the program can be used Call this native file.

Guess you like

Origin blog.csdn.net/u014365523/article/details/130159794