The JNA (Java Native Access) Framework is an open-source Java framework developed by SUN and built on the basis of the classic JNI. Very powerful and easy to use, similar to. net p/Invoke.
You only need to download a jar package and use the powerful functions of JNA to conveniently call the C function in the dynamic link library.
Download jna. jar
Download the latest version "JNA. jar" from the jna official website. The latest version is 3.4.0. The link is as follows:
Https://github.com/twall/jna
Install jna. jarMove the jna. jar file to the subdirectory of the JKD installation directory. my options are/java/jdk1.7.0/lib. This jna. jar file can also be placed in any directory, such as the Java project directory you are developing.
JNA example
Example 1
1. Introduce the jna. jar package in the Java project.
2. Create a class:
import com.sun.jna.Library;import com.sun.jna.Native;import com.sun.jna.Platform;public class HelloWorld { public interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class); void printf(String format, Object... args); } public static void main(String[] args) { CLibrary.INSTANCE.printf("Hello, World/n"); for (int i=0;i < args.length;i++) { CLibrary.INSTANCE.printf("Argument %d: %s/n", i, args[i]); } }}
3. Run the command. The output is displayed on the console.
Hello, World
However, please note that this program actually uses the printf function in the C Runtime Library msvcrt. dll to print out the above characters.
Example 2
The above example uses the dynamic link library provided by the operating system. Now we can try writing a dynamic link library by ourselves.
1. Select C ++ in VS and create a Win32 program. Select the dll type.
2. The released C function is:
# Define MYLIBAPI extern "C" _ declspec (dllexport)
MYLIBAPI void say (wchar_t * pValue );
The implementation of this function is:
Void say (wchar_t * pValue ){
Std: wcout. imbue (std: locale ("chs "));
Std: wcout <L "God says:" <pValue <std: endl;
}
It needs to input a Unicode character array. Then print a Chinese character in the console.
3. Generate the dll. Copy the generated dll file to the Eclipse project and place it under the project.
4. Write the following code:
Import com. sun. jna. library; import com. sun. jna. native; import com. sun. jna. WString; public class TestDll1Service {public interface TestDll1 extends Library {TestDll1 INSTANCE = (TestDll1) Native. loadLibrary ("TestDll1", TestDll1.class); public void say (WString value);} public TestDll1Service () {// TODO Auto-generated constructor stub} public static void main (String [] args) {// TODO Auto-generated m Ethod stub TestDll1.INSTANCE. say (new WString ("Hello World! "); System. out. println (" hheeh I can't do anything ");}}
5. Execute this Java class. The following output is displayed in the console:
God said: Hello World!
HHEEH, I can't do anything.
6. The above line is output by Using std: wcout of C ++.
The following line is output by the Java language.
How JNA works
JNA is a Java class library built on the basis of JNI technology. It allows you to conveniently use java to directly access functions in the dynamic link library.
If JNI is used, you must manually write a dynamic link library in C to map the Java data type in C.
In JNA, it provides a dynamic C language forwarder that can automatically implement data type ing between Java and C. You no longer need to write a C dynamic link library.
Of course, this also means that the use of JNA technology is slightly inferior to the use of JNI technology to call the dynamic link library. The speed may be several times lower. But it has little impact.
JNA technical difficulties
1. The current path is under the project rather than the bin output directory.
2. Data Structure: see the official website.
JNA Programming process
JNA regards a dll/. so file as a Java interface.
Dll is a collection and container of C functions, which is consistent with the concept of interfaces.
We define such an interface,
Public interface TestDll1 extends Library {
TestDll1 INSTANCE = (TestDll1) Native. loadLibrary ("TestDll1", TestDll1.class );
Public void say (WString value );
}
If the dll outputs the function in stdcall mode, it inherits StdCallLibrary. Otherwise, the default Library interface is inherited.
The interface requires a public static constant: instance.
TestDll1 INSTANCE = (TestDll1) Native. loadLibrary ("TestDll1", TestDll1.class );
Through this constant, you can obtain the instance of this interface and use the interface method. That is, the function that calls the external dll!
Note:
1. The Native. loadLibrary () function has two parameters:
The name of A, dll, or. so file without the suffix. This complies with the JNI specification, because it cannot be used across operating system platforms with the suffix.
The dll search path is:
1) Project root path
2) Global Path of the operating system,
3) path specified by path.
B. The second parameter is the Class type of this interface.
Through this Class type, JNA dynamically creates an interface instance based on the specified dll/. so file.
2. You only need to define the functions or public variables you need in the interface.
Public void say (WString value );
The type of the parameter and return value should be the same as the type of the C function in the dll.
This is JNA, and even all the difficulties in cross-platform calls.
Here, the function parameter of C language is: wchar_t *. The corresponding Java type in JNA is WStirng.
JNA Deficiency
JNA is a framework built on the basis of JNI technology. Using JNI technology, not only Java can access C functions, but also C language can call Java code. While JNA can only implement Java to access C functions. As a Java framework, it naturally cannot implement C language to call Java code. In this case, you still need to use JNI technology.
References:
Http://blog.csdn.net/shendl/archive/2008/12/23/3589676.aspx
Https://jna.dev.java.net/