In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "what is JNI". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what is JNI?"
First of all, let's review the main functions of jni. The jni standard has been part of the java platform since jdk1.1. It provides a series of API that allows java to interact with other languages and calls functions in other languages in java code. Through the call of jni, these functions can be realized:
Typically, we use jni to call code in c or C++. In the last article, we used the following process to describe the process of calling the native method:
Java Code-> JNI-> Compact + Code
But exactly this process is not rigorous, because in the end, it is not the original cripple + code that is executed, but the compiled and linked dynamic link library. Therefore, we upgrade this process from the simple code call level, and raise the jni call process to the jvm and operating system level, to add some details to improve:
See here, some friends may be about to ask questions, not to say that the java language is cross-platform, this interaction with the operating system locally compiled dynamic link libraries, will make java lose the portability of cross-platform?
To solve this problem, you can recall your previous experience of installing jdk. Different versions of jdk of each operating system, such as windows, linux, mac os, and so on, are provided in the download list on the official website. In these jdk, there are different jvm implementations for different systems. The cross-platform of java language happens to be closely related to its underlying jvm. It depends on the "translation" of different versions of jvm under different operating systems to make the compiled bytecode run smoothly on different platforms.
The dynamic link libraries generated by Cramp + or other codes may also vary in different operating systems, such as compiling to dll files on window platforms, so files on linux platforms, and jnilib files on mac os. On the other hand, jvm on different platforms will "conventionally" load a fixed type of dynamic link library file, so that functions dependent on the operating system can be called normally. This process can be understood by referring to the following figure:
After having a certain understanding of the overall calling process of jni, do you also wonder how it calls functions in other languages? let's understand its calling process by handwriting an example of java program calling C++ code.
1. Prepare the java code
First, we define a class that contains the native method as follows, and then we use the native method in this class to call the method in the dynamic link library written by C++ through jni:
Public class JniTest {static {System.loadLibrary ("MyNativeDll");} public static native void callCppMethod (); public static void main (String [] args) {System.out.println ("DLL path:" + System.getProperty ("java.library.path")); callCppMethod ();}}
The following work is mainly done in the code:
In the static code block, call the loadLibrary method to load the local dynamic link library, with the argument to the file name of the dynamic link library that does not contain the extension. The dll file is loaded on the window platform, the so file is loaded on the linux platform, and the jnilib file is loaded on the mac os platform.
A native method is declared, and the native keyword is responsible for informing jvm that the method is called here by a local method, which is defined externally
In the main method, print the path where the dll file is loaded and call the local method
2. Generate header file
You need to create an .h header file first when you implement the local method using c_. To put it simply, the ccontroller + program usually consists of a header file (.h) and a definition file (.c or .cpp). The header file contains the declaration of the function and data interface, while the definition file is used to write the implementation of the program.
In jdk8, you can directly use the javac-h instruction to generate a header file in the cplink + language. If you are using an earlier version of jdk, you need to execute javac to compile the class file, and then execute javah-jni to generate a jdk10-style header file (the javah directive has been removed in the new feature of jdk10). The jdk8 we use simplifies this step so that it can be done in one step, executing the command under the command line window:
Javac-h. / jni JniTest.java
The directive uses the-h argument to specify where to place the generated header file, and the final argument is the name of the java source file. In this process, two tasks are completed: first, the class file is generated, and then the header file is generated in the directory specified by the parameter. The generated header file com_cn_jni_JniTest.h contains the following:
/ * DO NOT EDIT THIS FILE-it is machine generated * / # include / * Header for class com_cn_jni_JniTest * / # ifndef _ Included_com_cn_jni_JniTest#define _ Included_com_cn_jni_JniTest#ifdef _ cplusplusextern "C" {# endif/* * Class: com_cn_jni_JniTest * Method: callCppMethod * Signature: () V * / JNIEXPORT void JNICALL Java_com_cn_jni_JniTest_callCppMethod (JNIEnv *, jclass); # ifdef _ _ cplusplus} # endif#endif
The generated header file is somewhat similar to the familiar java interface, with only the declaration of the function and no concrete implementation. Simply explain the code in the header file:
Extern "C" tells the compiler that this part of the code is compiled using C language rules.
JNIEXPORT and JNICALL are two macros defined in jni. Use JNIEXPORT to support calling methods in the dynamic library in external program code, and use JNICALL to define the stack-in-and-out convention for parameters when a function is called.
The function name consists of package name, class name and method name. In this method, there are two parameters. The object with the first parameter JNIEnv * can call a large number of functions encapsulated in jni.h. The second parameter represents the caller of the native method. When the native method defined in the java code is a static method, the parameter here is jclass, and the parameter of a non-static method is jobject.
Next, we create a cpp file, reference the header file and implement the functions in it, that is, the logic that the native method will actually execute:
# include "com_cn_jni_JniTest.h" # include JNIEXPORT void JNICALL Java_com_cn_jni_JniTest_callCppMethod (JNIEnv *, jclass) {printf ("Print From Cpp:\ n"); printf ("I am a cpp method!\ n");}
A simple printf print statement is added to the implementation of the method. After completing the implementation of the method, we need to compile the above cpp file into a dynamic link library and provide it to the native method call in java, so we need to install the gcc environment in the window environment.
3. Gcc environment installation
In window, if you don't want to download a bulky Visual Studio in order to generate a dll, MinGW is a good choice, simply a windows version of gcc. So maybe some students will ask again, what is gcc? To put it simply, it is the compiler of CumberCraft + under the linux system, through which the source code can be compiled into executable programs. First download the mingw-get-setup installer from the following URL:
Http://sourceforge.net/projects/mingw/ # 32 bit https://sourceforge.net/projects/mingw-w64/ # 64 bit
It should be noted that the corresponding version must be installed according to the number of digits of the system, otherwise the generated dll may report an error due to a mismatch in the number of digits. I mistakenly installed 32-bit MinGw for the first time in the course of the experiment, resulting in the following error reported during the running of the program:
Exception in thread "main" java.lang.UnsatisfiedLinkError: F:\ Workspace20\ unsafe-test\ src\ main\ java\ com\ cn\ jni\ jni\ MyNativeDll.dll: Can't load IA 32-bit .dll on an AMD 64-bit platform
After the installation is complete, add the MinGW\ bin directory to the system environment variable PATH, and enter the following instructions to test whether gcc can be used:
Gcc-v
If the gcc version information can be output normally, the gcc installation is successful:
During the test, it was found that if you installed a 64-bit mingw, the gcc would be available directly after the installation. However, if you are installing a 32-bit mingw, you need to install gcc separately using the following command:
Mingw-get install gcc
After the gcc installation is complete, if you want to install other instructions such as gdb or make for debugging or compilation, you can also use the powerful mingw-get command for stand-alone installation.
4. Generate dynamic link library
When the gcc environment is ready, next generate the dll dynamic link library using the following command:
Gcc-M64-Wl,--add-stdcall-alias-I "D:\ Program Files\ Java\ jdk1.8.0_261\ include"-I "D:\ Program Files\ Java\ jdk1.8.0_261\ include\ win32"-shared-o MyNativeDll.dll JniTestImpl.cpp
Simply explain the meaning of each parameter:
-M64: compiles cpp code into 64-bit applications
-Wl,--add-stdcall-alias:-Wl means to pass the following parameter to the linker, and the parameter-- add-stdcall-alias means that the symbol with the standard call suffix @ NN will be stripped and exported.
-I: specify the path to the header file, where the jni.h introduced in the generated header file code is located
-shared: specifies that a dynamic link library is generated. If this flag is not used, external programs will not be able to connect.
-o: specify the name of the target, where the generated dynamic link library is named MyNativeDll.dll
JniTestImpl.cpp: the file name of the compiled source program
You can refer to the following figure for what has been done during the execution of the instruction:
In the process of execution, the .cpp source code and .h header file are used as source files, and the operations of preprocessing, compilation and assembly are carried out first. some intermediate files generated at this stage are omitted in the diagram, and the .o binary file generated after compilation is relatively important. Rely on this file, and finally generate a dynamic link library.
After executing the above instructions, a MyNativeDll.dll file is generated in the current directory, and then the previously prepared java code is run:
The program reported an error because our dll file was not found in the default directory where the library files were loaded. There are two ways to solve this:
Copy the dll file directly to the default loading directory, and the specific path can be obtained through System.getProperty ("java.library.path"). This method may obtain multiple directories and put them in any one directory.
Modify the startup parameters in VM Option to specify the storage directory of dll:
-Djava.library.path=F:\ Workspace20\ unsafe-test\ src\ main\ java\ com\ cn\ jni\ jni
Execute again and output the result:
DLL path:F:\ Workspace20\ unsafe-test\ src\ main\ java\ com\ cn\ jni\ jniPrint From Cpp: I am a cpp method!
You can see that the path where the program loads dll has been switched to its storage path, and the jni call is successful, outputting the code logic in C++. You can use the following figure to summarize the process of implementing the jni call above:
After you have an overall understanding of the call of jni, if you are familiar with the proxy mode, you can also understand jni from the perspective of proxy mode and bring the roles in the process of jni call into the proxy mode:
Proxy role: jni class that contains native methods
Implementing roles: dynamic link libraries implemented in cUniverse + or other languages
Client: a java class program that calls the native method
Interface (abstract role): the role of interface in jni is relatively weak, because jni is cross-language, so it is impossible to strictly define an interface and apply it to both java and other languages. However, through the generated .h header file, to some extent, it unifies the native method in java and the functions in other languages from the interface specification.
Described in an overview diagram of the agent mode:
The above figure makes some modifications on the basis of the standard proxy pattern for easy understanding. Because the interface here only acts as a specification constraint, the calling process of the client skips the interface and points directly to the proxy role. Then the function of the role is called by the proxy role. In general, jni acts as an agent or intermediary, unlike common proxies, which only make method calls and do not implement logical enhancements. Through this pattern, we hide the implementation details of the underlying chopping + code from the java programmer, so that we can focus on writing the business code.
At this point, I believe you have a deeper understanding of "what is JNI", might as well come to the actual operation of it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.