JNI Study Notes (1) -- Character Set Conversion

Source: Internet
Author: User

The following methods always use the Java string: "Java/lang/string"

The root solution is fully implemented in native code. Open-source ICU or iconv is recommended.

Android uses an open-source Library: iconv, which is not exported by default.

Start with a code segment. This section mainly calls the constructor in Java. This code segment is implemented and Character Set conversion is performed.

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 above code is changed by referring to the javatm Native Interface programmer's guide and specification.

Here we will paste all the code for character set conversion and write it down for you to forget. In addition, it would be better if it is helpful to everyone.

To put it bluntly, it is actually calling the java. Lang. String method.

1. chartojstring.

2. jstringtochar.

MARK:

The following code will cause an error when converting a string of both Chinese and English characters, because it is char * in the parameter *. The more appropriate interface may be as follows:

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 calls are slower than Java/Java calls ~ Although native/Java calls are theoretically the same as Java/native calls, in fact, because the latter is much more efficient than the former, therefore, Java/native may get enough optimization, so that native/Java calls may be 10 times slower than Java/native calls.

/* * 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;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.