Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> JNI的字符串字符集轉換

JNI的字符串字符集轉換

編輯:Android開發實例

以下方式 總歸 還是在使用使用java的string:"java/lang/String"


 

治根的辦法 還是完整地在native code 中實現。推薦可以使用開源代碼icu 或者iconv


 

android本身也是用了開源的庫: iconv,只默認是未對外導出。


 

先放段代碼作為開頭,本段主要調用java中到構造函數,本段代碼實現,字符串字符集轉換。

 

  1. jstring  
  2. MyNewString(JNIEnv *env, const char *chars, jint len)  
  3. {  
  4.     jclass stringClass;  
  5.     jmethodID cid;  
  6.     jbyteArray elemArr;  
  7.     jstring result;  
  8.     jstring jencoding;  
  9.       
  10.     stringClass = env->FindClass("java/lang/String");  
  11.     if (stringClass == NULL) {  
  12.         return NULL; /* exception thrown */ 
  13.     }  
  14.  
  15.     /* Get the method ID for the String(byte[] data, String charsetName) constructor */ 
  16.     cid = env->GetMethodID(stringClass,"<init>", "([BLjava/lang/String;)V");  
  17.     if (cid == NULL) {  
  18.         return NULL; /* exception thrown */ 
  19.     }  
  20.  
  21.     jencoding = env->NewStringUTF("GBK");  
  22.     /* Create a byte[] that holds the string characters */ 
  23.     elemArr = env->NewByteArray(len);  
  24.     if (elemArr == NULL) {  
  25.         return NULL; /* exception thrown */ 
  26.     }  
  27.     env->SetByteArrayRegion(elemArr, 0, len, (jbyte*)chars);  
  28.     /* Construct a java.lang.String object */ 
  29.     result = (jstring)(env->NewObject(stringClass, cid, elemArr, jencoding));  
  30.     /* Free local references */ 
  31.     env->DeleteLocalRef(elemArr);  
  32.     env->DeleteLocalRef(stringClass);  
  33.     return result;  
  34. }  

以上代碼時是參照《The JavaTM Native Interface Programmer’s Guide and Specification》改的。

這裡將字符集轉換的全部代碼貼上,記下以備忘,此外如果對大家有幫助,那就更好了。

說穿了,其實就是在調用java.lang.String的方法。

一、CharToJString。

二、JStringToChar。


 

Mark:

以下代碼在轉中英文混合的字符串時會出錯,原因是參數中的char*。更合適的接口可能應該如下:

  1. jstring CharToJString(JNIEnv* env, const void* pszSrc, int nLen, const char* pszEncoding);  
  2. int JStringToChar(JNIEnv* env, jstring jstr, const char *pszEncoding, void* pszOutBuf, int nBufLen);  

java/native調用會比java/java調用慢上2~3倍,而雖然native/java調用,理論上和java/native效率一樣,可是,實際上,由於後者的使用比前者多得多,所以java/native可能得到了足夠多優化,這樣,native/java調用可能比java/native調用慢上10倍之多。
 

  1. <P></P><PRE class=cpp name="code">/*  
  2.  * you can use these function freely, but please keep this declaration with no modified.  
  3.  *  
  4.  * created by jerry.lin, 2011-08-04  
  5.  */ 
  6.  
  7.  
  8. #include <stdio.h>  
  9. #include <jni.h>  
  10. #include <string.h>  
  11.  
  12. /*  
  13.  * convert the char string to JString  
  14.  * parameter:  
  15.  *  [in]pszSrc: the source string to be converted.  
  16.  *  [in]pszEncoding: the encoding of pszSrc, if it is null, means utf8  
  17.  *  
  18.  * return value:  
  19.  *  return the convered string if is successful, otherwise return NULL.  
  20.  */ 
  21. jstring CharToJString(JNIEnv* env, const char* pszSrc, const char* pszEncoding)  
  22. {  
  23.     jstring jstr = NULL;  
  24.     jclass stringClass = NULL;  
  25.     jbyteArray byteElemArr = NULL;  
  26.  
  27.     do 
  28.     {  
  29.         jmethodID cid = NULL;  
  30.         jstring jstrEncoding = NULL;  
  31.         const char* pszEnco = NULL;  
  32.         int nStrLen = 0;  
  33.  
  34.         /* check the income parameters */ 
  35.         if (NULL == pszSrc || NULL == env)  
  36.         {  
  37.             break;  
  38.         }  
  39.  
  40.         /* get the String class of java and its constructor to create a new object */ 
  41.  
  42.         /* get the String class of java */ 
  43.         stringClass = env->FindClass("java/lang/String");  
  44.         if (NULL == stringClass)  
  45.         {  
  46.             break;  
  47.         }  
  48.  
  49.         /* Get the method ID for the java.lang.String constructor */ 
  50.         cid = env->GetMethodID(stringClass, "<init>", "([BLjava/lang/String;)V");  
  51.         if (NULL == cid)  
  52.         {  
  53.             break;  
  54.         }  
  55.  
  56.         if(NULL == pszEncoding)  
  57.         {  
  58.             pszEnco = "utf-8";  
  59.         }  
  60.         else 
  61.         {  
  62.             pszEnco = pszEncoding;  
  63.         }  
  64.         jstrEncoding = env->NewStringUTF(pszEnco);  
  65.         if (NULL == jstrEncoding)  
  66.         {  
  67.             break;  
  68.         }  
  69.  
  70.         /* put char string into array of java */ 
  71.         nStrLen = (int)strlen(pszSrc);  
  72.         byteElemArr = env->NewByteArray(nStrLen);  
  73.         if (NULL == byteElemArr)  
  74.         {  
  75.             break;  
  76.         }  
  77.         env->SetByteArrayRegion(byteElemArr, 0, nStrLen, (jbyte*)pszSrc);  
  78.  
  79.         /* create an new 0object of java.lang.String with the constructor string(byte[], string) */ 
  80.         jstr = (jstring)(env->NewObject(stringClass, cid, byteElemArr, jstrEncoding));  
  81.  
  82.     }while(0);  
  83.     /* Free local references */ 
  84.     if (NULL != byteElemArr)  
  85.     {  
  86.         env->DeleteLocalRef(byteElemArr);  
  87.     }  
  88.     if (NULL != stringClass)  
  89.     {  
  90.         env->DeleteLocalRef(stringClass);  
  91.     }  
  92.  
  93.     return jstr;  
  94. }  
  95.  
  96. /*  
  97.  * convert the JString to char string.  
  98.  *  
  99.  * parameter:  
  100.  *  [in]jstr: the source string to be converted.  
  101.  *  [in]pszEncoding: the encoding to which the JString to be converted.  
  102.  *  [out]pszOutBuf: the buffer to remain the changed string.  
  103.  *  [in] nBufLen: the length of the buffer.  
  104.  *  
  105.  * return value:  
  106.  *  the length of the string in bytes, that has been copied into pszOutBuf.  
  107.  */ 
  108. int JStringToChar(JNIEnv* env, jstring jstr, const char *pszEncoding, char* pszOutBuf, int nBufLen)  
  109. {  
  110.     int nRet = -1;  
  111.     jclass stringClass = NULL;  
  112.     jbyteArray byteElemArr = NULL;  
  113.  
  114.     do 
  115.     {  
  116.         jmethodID cid = NULL;  
  117.         jstring jstrEncoding = NULL;  
  118.         const char* pszEnco = NULL;  
  119.         int nStrLen = 0;  
  120.  
  121.         /* check the income parameters */ 
  122.         if (NULL == jstr || NULL == env)  
  123.         {  
  124.             break;  
  125.         }  
  126.  
  127.         /* get the String class of java */ 
  128.         stringClass = env->FindClass("java/lang/String");  
  129.         if (NULL == stringClass)  
  130.         {  
  131.             break;  
  132.         }  
  133.  
  134.         /* Get the method ID for the java.lang.String getBytes(String) */ 
  135.         cid = env->GetMethodID(stringClass, "getBytes", "(java/lang/String;)[B");  
  136.         if (NULL == cid)  
  137.         {  
  138.             break;  
  139.         }  
  140.  
  141.         if(NULL == pszEncoding)  
  142.         {  
  143.             pszEnco = "utf-8";  
  144.         }  
  145.         else 
  146.         {  
  147.             pszEnco = pszEncoding;  
  148.         }  
  149.         jstrEncoding = env->NewStringUTF(pszEnco);  
  150.         if (NULL == jstrEncoding)  
  151.         {  
  152.             break;  
  153.         }  
  154.  
  155.         /* get char string into array with designated encode */ 
  156.         byteElemArr = (jbyteArray)env->CallObjectMethod(jstr, cid, jstrEncoding);  
  157.         if (NULL == byteElemArr)  
  158.         {  
  159.             break;  
  160.         }  
  161.         nStrLen = (int)(env->GetArrayLength(byteElemArr));  
  162.         /* to return the length of the char string, if nBufLen is 0, or pszOutBuf is NULL */ 
  163.         if (0 == nBufLen || NULL == pszOutBuf)  
  164.         {  
  165.             nRet = nStrLen;  
  166.             break;  
  167.         }  
  168.  
  169.         /* if the nBufLen < nStrLen, return failed */ 
  170.         if (nBufLen < nStrLen)  
  171.         {  
  172.             nRet = -2;  
  173.             break;  
  174.         }  
  175.  
  176.         /* get the content of the byteArray, and copy into the out buffer */ 
  177.         jbyte* pszBytes = env->GetByteArrayElements(byteElemArr, JNI_FALSE);  
  178.         if (NULL != pszBytes)  
  179.         {  
  180.             memcpy(pszOutBuf, pszBytes, nStrLen);  
  181.             pszOutBuf[nStrLen] = 0;  
  182.             nRet = nStrLen;  
  183.         }  
  184.  
  185.     }while(0);  
  186.     /* Free local references */ 
  187.     if (NULL != byteElemArr)  
  188.     {  
  189.         env->DeleteLocalRef(byteElemArr);  
  190.     }  
  191.     if (NULL != stringClass)  
  192.     {  
  193.         env->DeleteLocalRef(stringClass);  
  194.     }  
  195.  
  196.     return nRet;  
  197. }  
  198. </PRE><BR>  
  199. <BR>  
  200. <P></P>  
  201. <P><BR>  
  202. </P>  
  203. <PRE></PRE>  
  204. <PRE></PRE> 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved