Tags标签 网战地图
当前位置: 主页 > 编程语言 > Android >

JNI的字符串字符集转换

2014-06-06 13:53 [Android] 来源于:
导读:以下方式 总归 还是在使用使用java的string:java/lang/String 治根的办法 还是完整地在native code 中实现。推荐可以使用开源代码icu 或者iconv android本身也是用了开源的库:iconv,只默认是未对外导出。 先放段代码作为开头,本段主要调用java中到构造函

以下方式 总归 还是在使用使用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> 

(编辑:)

本文标签:
网友评论

栏目列表

推荐文章