JNI 學習筆記(一)——字串字元集轉換

來源:互聯網
上載者:User

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

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

android本身也是用了開源的庫: iconv,只預設是未對外匯出。

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

jstringMyNewString(JNIEnv *env, const char *chars, jint len){jclass stringClass;jmethodID cid;jbyteArray elemArr;jstring result;jstring jencoding;stringClass = env->FindClass("java/lang/String");if (stringClass == NULL) {return NULL; /* exception thrown */}/* Get the method ID for the String(byte[] data, String charsetName) constructor */cid = env->GetMethodID(stringClass,"<init>", "([BLjava/lang/String;)V");if (cid == NULL) {return NULL; /* exception thrown */}jencoding = env->NewStringUTF("GBK");/* Create a byte[] that holds the string characters */elemArr = env->NewByteArray(len);if (elemArr == NULL) {return NULL; /* exception thrown */}env->SetByteArrayRegion(elemArr, 0, len, (jbyte*)chars);/* Construct a java.lang.String object */result = (jstring)(env->NewObject(stringClass, cid, elemArr, jencoding));/* Free local references */env->DeleteLocalRef(elemArr);env->DeleteLocalRef(stringClass);return result;}

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

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

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

一、CharToJString。

二、JStringToChar。

Mark:

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

jstring CharToJString(JNIEnv* env, const void* pszSrc, int nLen, const char* pszEncoding);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倍之多。

/* * you can use these function freely, but please keep this declaration with no modified. * * created by jerry.lin, 2011-08-04 */#include <stdio.h>#include <jni.h>#include <string.h>/* * convert the char string to JString * parameter: *[in]pszSrc: the source string to be converted. *[in]pszEncoding: the encoding of pszSrc, if it is null, means utf8 * * return value: * return the convered string if is successful, otherwise return NULL. */jstring CharToJString(JNIEnv* env, const char* pszSrc, const char* pszEncoding){jstring jstr = NULL;jclass stringClass = NULL;jbyteArray byteElemArr = NULL;do{jmethodID cid = NULL;jstring jstrEncoding = NULL;const char* pszEnco = NULL;int nStrLen = 0;/* check the income parameters */if (NULL == pszSrc || NULL == env){break;}/* get the String class of java and its constructor to create a new object *//* get the String class of java */stringClass = env->FindClass("java/lang/String");if (NULL == stringClass){break;}/* Get the method ID for the java.lang.String constructor */cid = env->GetMethodID(stringClass, "<init>", "([BLjava/lang/String;)V");if (NULL == cid){break;}if(NULL == pszEncoding){pszEnco = "utf-8";}else{pszEnco = pszEncoding;}jstrEncoding = env->NewStringUTF(pszEnco);if (NULL == jstrEncoding){break;}/* put char string into array of java */nStrLen = (int)strlen(pszSrc);byteElemArr = env->NewByteArray(nStrLen);if (NULL == byteElemArr){break;}env->SetByteArrayRegion(byteElemArr, 0, nStrLen, (jbyte*)pszSrc);/* create an new 0object of java.lang.String with the constructor string(byte[], string) */jstr = (jstring)(env->NewObject(stringClass, cid, byteElemArr, jstrEncoding));}while(0);/* Free local references */if (NULL != byteElemArr){env->DeleteLocalRef(byteElemArr);}if (NULL != stringClass){env->DeleteLocalRef(stringClass);}return jstr;}/* * convert the JString to char string. * * parameter: * [in]jstr: the source string to be converted. * [in]pszEncoding: the encoding to which the JString to be converted. * [out]pszOutBuf: the buffer to remain the changed string. * [in] nBufLen: the length of the buffer. * * return value: *the length of the string in bytes, that has been copied into pszOutBuf. */int JStringToChar(JNIEnv* env, jstring jstr, const char *pszEncoding, char* pszOutBuf, int nBufLen){int nRet = -1;jclass stringClass = NULL;jbyteArray byteElemArr = NULL;do{jmethodID cid = NULL;jstring jstrEncoding = NULL;const char* pszEnco = NULL;int nStrLen = 0;/* check the income parameters */if (NULL == jstr || NULL == env){break;}/* get the String class of java */stringClass = env->FindClass("java/lang/String");if (NULL == stringClass){break;}/* Get the method ID for the java.lang.String getBytes(String) */cid = env->GetMethodID(stringClass, "getBytes", "(java/lang/String;)[B");if (NULL == cid){break;}if(NULL == pszEncoding){pszEnco = "utf-8";}else{pszEnco = pszEncoding;}jstrEncoding = env->NewStringUTF(pszEnco);if (NULL == jstrEncoding){break;}/* get char string into array with designated encode */byteElemArr = (jbyteArray)env->CallObjectMethod(jstr, cid, jstrEncoding);if (NULL == byteElemArr){break;}nStrLen = (int)(env->GetArrayLength(byteElemArr));/* to return the length of the char string, if nBufLen is 0, or pszOutBuf is NULL */if (0 == nBufLen || NULL == pszOutBuf){nRet = nStrLen;break;}/* if the nBufLen < nStrLen, return failed */if (nBufLen < nStrLen){nRet = -2;break;}/* get the content of the byteArray, and copy into the out buffer */jbyte* pszBytes = env->GetByteArrayElements(byteElemArr, JNI_FALSE);if (NULL != pszBytes){memcpy(pszOutBuf, pszBytes, nStrLen);pszOutBuf[nStrLen] = 0;nRet = nStrLen;}}while(0);/* Free local references */if (NULL != byteElemArr){env->DeleteLocalRef(byteElemArr);}if (NULL != stringClass){env->DeleteLocalRef(stringClass);}return nRet;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.