Java调用Native API之JNA

字体大小: 中小 标准 ->行高大小: 标准
Java调用C/C++的Native API一般采用JNI(Java Native Interface),但是需要编写特殊的代码,方法、数据的映射也很复杂。JNA(Java Native Access)能够是Java代码很简单的调用到Native API(.dll、.so)。类似于.NET的P/Invoke(Platform Invoke)、Python的ctypes。最初是1999年SUN公司为开发NetBeans IDE而开发的,2006年开源。 

https://github.com/twall/jna 

目前版本: 4.1.0 

先看一个简单的例子:调用Windows API的printf输出“Hello, World”。 

JNA代码: 
Java代码  
  1. import com.sun.jna.Library;  
  2. import com.sun.jna.Native;  
  3. import com.sun.jna.Platform;  
  4.   
  5. public class HelloWorld1 {  
  6.     public interface CLibrary extends Library {  
  7.         CLibrary INSTANCE = (CLibrary) Native.loadLibrary(  
  8.             Platform.isWindows() ? "msvcrt" : "c", CLibrary.class);  
  9.   
  10.         void printf(String format, Object... args);  
  11.     }  
  12.   
  13.     public static void main(String[] args) {  
  14.         CLibrary.INSTANCE.printf("Hello, World\n");  
  15.     }  
  16. }  

第6行定义CLibrary映射到Native(继承JNA的Library) 
第7,8行加载目标Native Lib(Windows:msvcrt.dll,也可以是自己的so或dll) 
第10行映射Native方法 
第14行作为Java的普通方法调用printf 

这是一种静态的映射方法,以下也可以动态映射: 
Java代码  
  1. import com.sun.jna.Function;  
  2. import com.sun.jna.Platform;  
  3.   
  4. public class HelloWorld2 {  
  5.     public static void main(String[] args) {  
  6.         String libraryName  = Platform.isWindows() ? "msvcrt" : "c";  
  7.         String functionName = "printf";  
  8.   
  9.         // Function  
  10.         Function function = Function.getFunction(  
  11.             libraryName,  
  12.             functionName,  
  13.             Function.C_CONVENTION);  
  14.   
  15.         // Invoke  
  16.         function.invoke(new Object[]{"Hello, world\n"});  
  17.     }  
  18. }  


JNI来实现调用C写的方法: 
1)编写HelloWorld.java 
Java代码  
  1. /* HelloWorld.java */  
  2. public class HelloWorld {  
  3.   public native void hello(); /* (1) */  
  4.   static {  
  5.     System.loadLibrary("helloworld"); /* (2) */  
  6.   }  
  7.   public static void main (String args[]) {  
  8.     HelloWorld h = new HelloWorld();  
  9.     h.hello(); /* (3) */  
  10.   }  
  11. }  

2)编译java文件 
引用
/usr/java/jdk1.7.0_45/bin/javac HelloWorld.java

3)生成JNI的HelloWorld.h 
引用
/usr/java/jdk1.7.0_45/bin/javah -jni HelloWorld

C代码  
  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class HelloWorld */  
  4.   
  5. #ifndef _Included_HelloWorld  
  6. #define _Included_HelloWorld  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /* 
  11.  * Class:     HelloWorld 
  12.  * Method:    hello 
  13.  * Signature: ()V 
  14.  */  
  15. JNIEXPORT void JNICALL Java_HelloWorld_hello  
  16.   (JNIEnv *, jobject);  
  17.   
  18. #ifdef __cplusplus  
  19. }  
  20. #endif  
  21. #endif  

4)编写HelloWorld.c 
C代码  
  1. #include "HelloWorld.h"  
  2.   
  3. JNIEXPORT void JNICALL Java_HelloWorld_hello  
  4.   (JNIEnv *env, jobject me)  
  5. {  
  6.   printf("Hello World\n");  
  7. }  

5)编译HelloWorld.c 
引用
gcc -fPIC -shared HelloWorld.c -I/usr/java/jdk1.7.0_45/include/ -I/usr/java/jdk1.7.0_45/include/linux/ -o libhelloworld.so

6)执行HelloWorld 
引用
java -Djava.library.path=. HelloWorld


JNA来实现调用C写的方法: 

1)编写hello.c 
C代码  
  1. #include <stdio.h>  
  2.   
  3. void hello ()  
  4. {  
  5.   printf("Hello World!\n");  
  6. }  


2)编译hello.c 
引用
gcc -fPIC -shared -o libhello.so hello.c


3)编写HelloJNA.java 
Java代码  
  1. import com.sun.jna.Library;  
  2. import com.sun.jna.Native;  
  3.   
  4. interface HelloLib extends Library {  
  5.   HelloLib INSTANCE = (HelloLib) Native.loadLibrary("hello", HelloLib.class);  
  6.   
  7.   void hello();  
  8. }  
  9.   
  10. public class HelloJNA {  
  11.   public static void main(String[] args){  
  12.     HelloLib hello = HelloLib.INSTANCE;  
  13.     hello.hello();  
  14.   }  
  15. }  


4)编译执行 
引用
javac -cp jna-4.1.0.jar HelloJNA.java 
java -cp .:jna-4.1.0.jar HelloJNA


参考: 
http://en.wikipedia.org/wiki/Java_Native_Access 
http://en.wikipedia.org/wiki/Java_Native_Interface 
http://en.wikipedia.org/wiki/SWIG 
http://www.swig.org/ 
http://en.wikipedia.org/wiki/Platform_Invocation_Services 
http://www.atmarkit.co.jp/fjava/special/jna/jna_1.html

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/68306.html