Java调用C(Linux下实现Java本地方法)

来源:互联网 发布:河北大学新区淘宝地址 编辑:程序博客网 时间:2024/05/20 09:10

一、Java类中声明本地方法,使用native关键字

[java] view plaincopyprint?
  1. public class MyNative {  
  2.     public void showParms(String s, int i, boolean b) {  
  3.         showParms0(s, i, b);  
  4.     }  
  5.     public int hypotenuse(int a, int b) {  
  6.         return hypotenuse0(a, b);  
  7.     }  
  8.     public void setArray(boolean[] ba) {  
  9.         for (int i = 0; i < ba.length; i++)  
  10.             ba[i] = true;  
  11.         setArray0(ba);  
  12.     }  
  13.     public void showStrings(String[] sa) {  
  14.         showStrings0(sa);  
  15.     }  
  16.     public String[] getStrings() {  
  17.         return getStrings0();  
  18.     }  
  19.     private native void showParms0(String s, int i, boolean b);  
  20.     private native int hypotenuse0(int a, int b);  
  21.     private native void setArray0(boolean[] ba);  
  22.     private native void showStrings0(String[] sa);  
  23.     private native String[] getStrings0();  
  24.     static {  
  25.         System.loadLibrary("MyNative");  
  26.     }  
  27.     public static void main(String[] args) {  
  28.         MyNative obj = new MyNative();  
  29.         obj.showParms("Hello"23true);  
  30.         obj.showParms("World"34false);  
  31.         System.out.println(obj.hypotenuse(34));  
  32.         System.out.println(obj.hypotenuse(912));  
  33.         boolean[] ba = new boolean[5];  
  34.         obj.setArray(ba);  
  35.         for (int i = 0; i < ba.length; i++)  
  36.             System.out.println(ba[i]);  
  37.         String[] sa = new String[] { "Hello,""world!""JNI""is""fun." };  
  38.         obj.showStrings(sa);  
  39.         obj.showStrings(obj.getStrings());  
  40.     }  
  41. }  

loadLibrary

public static void loadLibrary(String libname)
Loads the system library specified by the libname argument. The manner in which a library name is mapped to the actual system library is system dependent.

The call System.loadLibrary(name) is effectively equivalent to the call

 Runtime.getRuntime().loadLibrary(name) 

 

Parameters:
libname - the name of the library.
Throws:
SecurityException- if a security manager exists and its checkLink method doesn't allow loading of the specified dynamic library
UnsatisfiedLinkError- if the library does not exist.
NullPointerException- if libname is null
See Also:
Runtime.loadLibrary(java.lang.String), SecurityManager.checkLink(java.lang.String)

二、生成.class文件,并使用javah命令,将.class文件生成.h文件

[java] view plaincopyprint?
  1. javac MyNative.class  
  2. javah -jni MyNative  

生成的.h文件如下

[cpp] view plaincopyprint?
  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>   
  3. /* Header for class MyNative */  
  4. #ifndef _Included_MyNative   
  5. #define _Included_MyNative  
  6. #ifdef __cplusplus   
  7. extern "C" {  
  8. #endif   
  9. /* 
  10.  * Class:     MyNative 
  11.  * Method:    getStrings0 
  12.  * Signature: ()[Ljava/lang/String; 
  13.  */  
  14. JNIEXPORT jobjectArray JNICALL Java_MyNative_getStrings0  
  15.   (JNIEnv *, jobject);  
  16. /* 
  17.  * Class:     MyNative 
  18.  * Method:    showStrings0 
  19.  * Signature: ([Ljava/lang/String;)V 
  20.  */  
  21. JNIEXPORT void JNICALL Java_MyNative_showStrings0  
  22.   (JNIEnv *, jobject, jobjectArray);  
  23. /* 
  24.  * Class:     MyNative 
  25.  * Method:    showParms0 
  26.  * Signature: (Ljava/lang/String;IZ)V 
  27.  */  
  28. JNIEXPORT void JNICALL Java_MyNative_showParms0  
  29.   (JNIEnv *, jobject, jstring, jint, jboolean);  
  30. /* 
  31.  * Class:     MyNative 
  32.  * Method:    hypotenuse0 
  33.  * Signature: (II)I 
  34.  */  
  35. JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0  
  36.   (JNIEnv *, jobject, jint, jint);  
  37. /* 
  38.  * Class:     MyNative 
  39.  * Method:    setArray0 
  40.  * Signature: ([Z)V 
  41.  */  
  42. JNIEXPORT void JNICALL Java_MyNative_setArray0  
  43.   (JNIEnv *, jobject, jbooleanArray);  
  44. #ifdef __cplusplus   
  45. }  
  46. #endif   
  47. #endif  

三、将刚刚生成的.h文件包含在头文件中,并用C语言实现这些本地方法,代码如下

[cpp] view plaincopyprint?
  1. #include <stdio.h>   
  2. #include <math.h>   
  3. #include "MyNative.h"   
  4. JNIEXPORT void JNICALL Java_MyNative_showParms0  
  5.   (JNIEnv *env, jobject obj, jstring s, jint i, jboolean b)  
  6. {  
  7.   const char* szStr = (*env)->GetStringUTFChars( env, s, 0 );  
  8.   printf( "String = [%s]/n", szStr );  
  9.   printf( "int = %d/n", i );  
  10.   printf( "boolean = %s/n", (b==JNI_TRUE ? "true" : "false") );  
  11.   (*env)->ReleaseStringUTFChars( env, s, szStr );  
  12. }  
  13. JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0  
  14.   (JNIEnv *env, jobject obj, jint a, jint b)  
  15. {  
  16.   int rtn = (int)sqrt( (double)( (a*a) + (b*b) ) );  
  17.   return (jint)rtn;  
  18. }  
  19. JNIEXPORT void JNICALL Java_MyNative_setArray0  
  20.   (JNIEnv *env, jclass cls, jbooleanArray ba)  
  21. {  
  22.   jboolean* pba = (*env)->GetBooleanArrayElements( env, ba, 0 );  
  23.   jsize len = (*env)->GetArrayLength(env, ba);  
  24.   int i=0;  
  25.   // 更改偶数数组元素   
  26.   for( i=0; i < len; i+=2 )  
  27.     pba[i] = JNI_FALSE;  
  28.   (*env)->ReleaseBooleanArrayElements( env, ba, pba, 0 );  
  29. }  
  30. JNIEXPORT void JNICALL Java_MyNative_showStrings0  
  31.   (JNIEnv *env, jclass cls, jobjectArray sa)  
  32. {  
  33.   int len = (*env)->GetArrayLength( env, sa );  
  34.   int i=0;  
  35.   for( i=0; i < len; i++ )  
  36.   {  
  37.     jobject obj = (*env)->GetObjectArrayElement(env, sa, i);  
  38.     jstring str = (jstring)obj;  
  39.     const char* szStr = (*env)->GetStringUTFChars( env, str, 0 );  
  40.     printf( "%s ", szStr );  
  41.     (*env)->ReleaseStringUTFChars( env, str, szStr );  
  42.   }  
  43.   printf( "/n" );  
  44. }  
  45. JNIEXPORT jobjectArray JNICALL Java_MyNative_getStrings0  
  46.   (JNIEnv *env, jclass cls)  
  47. {  
  48.   jstring      str;  
  49.   jobjectArray args = 0;  
  50.   jsize        len = 5;  
  51.   char*        sa[] = { "Hello,""world!""JNI""is""fun" };  
  52.   int          i=0;  
  53.   args = (*env)->NewObjectArray(env, len, (*env)->FindClass(env, "java/lang/String"), 0);  
  54.   for( i=0; i < len; i++ )  
  55.   {  
  56.     str = (*env)->NewStringUTF( env, sa[i] );  
  57.     (*env)->SetObjectArrayElement(env, args, i, str);  
  58.   }  
  59.   return args;  
  60. }  

四、书写makefile文件,编译刚才所写的C代码,生成.so文件,Linux环境下(windows,DLL文件)

[c-sharp] view plaincopyprint?
  1. libMyNative.so:MyNative.o makefile  
  2.     gcc -Wall -rdynamic -shared -o libMyNative.so MyNative.o  
  3.     MyNative.o:MyNative.c MyNative.h  
  4.     gcc -Wall -c MyNative.c -I./ -I/sandbox/JAVA2S/jdk1.6.0_16/include -I/sandbox/JAVA2S/jdk1.6.0_16/include/linux  
  5. cl:  
  6.     rm -rf *.o *.so  

其中,“/sandbox/JAVA2S/jdk1.6.0_16”为JDK安装目录

“libMyNative.so”是Java类中

    static {
        System.loadLibrary("MyNative");
    }

静态方法中参数+lib

五、修改.bash_profile文件,配置环境变量,由于生成的.so文件在当前目录下,故

.bash_profile文件设置如下


export LD_LIBRARY_PATH=./

 

六、执行java MyNative命令,结果如下



Linux下实现Java本地方法(Java调用C)完成。

 

参考资料:

http://www.ibm.com/developerworks/cn/java/jnimthds/index.html


0 0
原创粉丝点击