Java如何調用C代碼–(Linux下實現Java本地方法)

來源:互聯網
上載者:User

原文:Java調用C(Linux下實現Java本地方法)

 

 

一、Java類中聲明本地方法,使用native關鍵字

 

  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", 23, true);  
  30.         obj.showParms("World", 34, false);  
  31.         System.out.println(obj.hypotenuse(3, 4));  
  32.         System.out.println(obj.hypotenuse(9, 12));  
  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、.h檔案

  1. javac MyNative.class  
  2. javah -jni MyNative  

 

產生的.h檔案如下

 

  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  

 

三、用C語言實現.h檔案中聲明的方法

     將剛剛產生的.h檔案包含在標頭檔中,並用C語言實現這些本地方法,代碼如下

 

  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. }  

 

四、編譯C語言檔案

     書寫makefile檔案,編譯剛才所寫的C代碼,產生.so檔案,Linux環境下(windows,DLL檔案)

 

  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

 

 

 

Tags:

Java和C、C++語言混合使用,Java如何調用C語言,Java如何調用C++語言,Java JNI的實現,Java本地調用方法。

 

轉自:http://blog.csdn.net/kangkanglou/archive/2010/08/13/5807787.aspx

作者:kangkang_kevin

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.