文章出處

 

如果沒有配置環境變量,先配置環境變量,如下:

1、右鍵我的電腦——高級——環境變量——下面的系統變量

2、選擇【新建系統變量】--彈出“新建系統變量”對話框,在“變量名”文本框輸入“JAVA_HOME”,在“變量值”文本框輸入JDK的安裝路徑,單擊“確定”。

3、在“系統變量”選項區域中查看PATH變量,如果不存在,則新建變量 PATH,否則選中該變量,單擊“編輯”按鈕,在“變量值”文本框的起始位置添加“%JAVA_HOME%\bin;%JAVA_HOME%\jre \bin;”或者是直接“%JAVA_HOME%\bin;”

4、在“系統變量”選項區域中查看CLASSPATH 變量,如果不存在,則新建變量CLASSPATH,否則選中該變量,單擊“編輯”按鈕,在“變量值”文本框的起始位置添加 “.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;”

5、現在測試環境變量的配置成功與否。在DOS命令行窗口輸入“JAVAC”,輸出幫助信息即為配置正確

 6、 在命令行下輸入以下命令: java -version 將顯示JDK的版本信息

 

 

先看現象:

1. .h文件

JNIEXPORT jintArray JNICALL Java_com_example_testjni_MainActivity_getByteArrayFromC
  (JNIEnv *, jobject, jcharArray);

 

2. .c主函數

JNIEXPORT jintArray JNICALL Java_com_example_testjni_MainActivity_getByteArrayFromC
  (JNIEnv * env, jobject jobj, jcharArray jcarr){
 jcarr.
 return (*env)->NewIntArray(env,cstr);
}

 

3. .c成員函數

/**
 * 返回值 char* 這個代表char數組的首地址
 *  Jstring2CStr 把java中的jstring的類型轉化成一個c語言中的char 字符串
 */
char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
{
  char*   rtn   =   NULL;
  jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String"); //String
  jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");  // 得到一個java字符串 "GB2312"
  jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");
  jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
  jsize   alen   =   (*env)->GetArrayLength(env,barr); // byte數組的長度
  jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
  if(alen   >   0)
  {
   rtn   =   (char*)malloc(alen+1);         //"\0"
   memcpy(rtn,ba,alen);
   rtn[alen]=0;
  }
  (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //
  return rtn;
}

 

4. jni.h中的靜態函數

接口: jmethodID   (*FromReflectedMethod)(JNIEnv*, jobject);

函數: jintArray     (*NewIntArray)(JNIEnv*, jsize);

重載: jintArray NewIntArray(jsize length)
    { return functions->NewIntArray(this, length); }

 

發現:

 

所有的JNI調用都使用了JNIEnv*類型的指針,習慣上在CPP文件中將這個變量定義為env,它是任意一個本地方法的第一個參數。env指針指向一個函數指針表,在VC中可以直接用"->"操作符訪問其中的函數。

    jobject 指向在此 Java 代碼中實例化的 Java 對象 LocalFunction的一個句柄,相當于this指針。后續的參數就是本地調用中有Java程序傳進的參數,本例中只有一個String型參數。對于字符串型參數,因為在本地代碼中不能直接讀取Java字符串,而必須將其轉換為C/C++字符串或Unicode。以下是我們經常會用到的字符串類型處理的函數:

(1)   const char* GetStringUTFChars (jstring string,jboolean* isCopy)
返回指向字符串UTF編碼的指針,如果不能創建這個字符數組,返回null。這個指針在調用ReleaseStringUTFChar()函數之前一直有效。 參數:
string Java字符串對象 
isCopy 如果進行拷貝,指向以JNI_TRUE填充的jboolean,否則指向以JNI_FALSE填充的jboolean。

(2)   void ReleaseStringUTFChars(jstring str, const char* chars)
通知虛擬機本地代碼不再需要通過chars訪問Java字符串。 
參數:
string Java字符串對象 
chars 由GetStringChars返回的指針

(3)   jstring NewStringUTF(const char *utf)
返回一個新的Java字符串并將utf內容拷貝入新串,如果不能創建字符串對象,返回null。通常在反值類型為string型時用到。 
參數:
utf UTF編碼的字符串指針,對于數值型參數,在C/C++中可直接使用,其字節寬度如下所示:

 

 

 

 

對于上述類型數組,有一組函數與之對應,以下函數中Xxx為對應類型。
xxx* GetXxxArrayElements(xxxArray array, jboolean *isCopy)
產生一個指向Java數組元素的C指針。不再需要時,需將此指針傳給Relea***xxArrayElements
參數:
array 數組對象 
isCopy 如果進行拷貝,指向以JNI_TRUE填充的jboolean,否則指向以JNI_FALSE填充的jboolean。 
例如:jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy)

(4)   void Relea***xxArrayElements(xxxArray array,xxx *elems, jint mode)
通知虛擬機不再需要從GetXxxArrayElements得到的指針。 
參數:
array 數組對象 
elems 不再需要的指向數組元素的指針 
mode 0=在更新數組元素后釋放elems緩沖器 
JNI_COMMIT=在更新數組元素后不釋放elems緩沖器 
JNI_ABORT=不更新數組元素釋放elems緩沖器 
例如:void ReleaseBooleanArrayElements(jbooleanArray array,jboolean *elems, jint mode)

(5)   xxxArray NewXxxArray(jsize len)
產生一個新的數組,通常在反值類型為數組型時用到。
參數:
len 數組中元素的個數。 
例如:jbooleanArray NewBooleanArray(jsize len)

http://blog.csdn.net/omg_2012/article/details/8175398


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()