首先建立Test.java,然後使用javac Test.java編譯的到Test.class,然後再使用javah -jni Test得到Test.h,然後建立Test.c並且include “Test.h"並實現相應的本地方法。這些步驟做好之後使用如下命令將Test.c編譯成動態連結程式庫:
gcc -c Test.c
gcc -shared -fPCI -o libtest.so Test.o
注意:需要先將jni.h和jni_md.h拷貝到目前的目錄中,並且將jni.h中的<jni_md.h>改成"jni_md.h",將Test.h中的<jni_md.h>改為"jni_md.h"。
相關原始碼如下:
/***********Test.java***************/public class Test{ static{ System.loadLibrary("test"); } public Test(){ System.out.println(getString()); String str="Hello,BBBBBBBBBBBBBBA"; showString(str); } public native String getString(); public native void showString(String str); public static void main(String[] args){ new Test(); }}
/***************Test.h****************//* DO NOT EDIT THIS FILE - it is machine generated */#include "jni.h"/* Header for class Test */#ifndef _Included_Test#define _Included_Test#ifdef __cplusplusextern "C" {#endif/* * Class: Test * Method: getString * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_Test_getString (JNIEnv *, jobject);/* * Class: Test * Method: showString * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_Test_showString (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif
/************Test.c***************/#include "Test.h"#include <string.h>#include <stdio.h>#include <stdlib.h>jstring CStr2Jstring( JNIEnv* env, const char* pat ){ //定義java String類 strClass jclass strClass = (*env)->FindClass(env,"Ljava/lang/String;"); //擷取java String類方法String(byte[],String)的構造器,用於將本地byte[]數群組轉換為一個新String jmethodID ctorID = (*env)->GetMethodID(env,strClass, "<init>", "([BLjava/lang/String;)V"); //建立byte數組 jbyteArray bytes = (*env)->NewByteArray(env,(jsize)strlen(pat)); //將char* 轉換為byte數組 (*env)->SetByteArrayRegion(env,bytes, 0, (jsize)strlen(pat), (jbyte*)pat); //設定String, 儲存語言類型,用於byte數群組轉換至String時的參數 jstring encoding = (*env)->NewStringUTF(env,"GB2312"); //將byte數群組轉換為java String,並輸出 return (jstring)(*env)->NewObject(env,strClass, ctorID, bytes, encoding); }char* Jstring2CStr(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = (*env)->FindClass(env,"java/lang/String"); jstring strencode = (*env)->NewStringUTF(env,"GB2312"); jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); jsize alen = (*env)->GetArrayLength(env,barr); jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE); if(alen > 0) { rtn = (char*)malloc(alen+1); //new char[alen+1]; memcpy(rtn,ba,alen); rtn[alen]=0; } (*env)->ReleaseByteArrayElements(env,barr,ba,0); return rtn;} JNIEXPORT jstring JNICALL Java_Test_getString (JNIEnv *env, jobject obj){ char *mychar="Hello,AAAAAAAAAAAAAAAAAB"; return CStr2Jstring(env,mychar);}JNIEXPORT void JNICALL Java_Test_showString (JNIEnv *env, jobject obj, jstring str){ char *mychar=Jstring2CStr(env,str); printf("-->%s<--\n",mychar);}
程式編譯運行環境:
root@ubuntu:/home/kyc# javac -version
javac 1.6.0_27
root@ubuntu:/home/kyc# java -version
java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~12.04)
OpenJDK Server VM (build 20.0-b12, mixed mode)
程式運行:
(--------------完----------------)