以下方式 总归 还是在使用使用java的string:"java/lang/String"
治根的办法 还是完整地在native code 中实现。推荐可以使用开源代码icu 或者iconv
android本身也是用了开源的库: iconv,只默认是未对外导出。
先放段代码作为开头,本段主要调用java中到构造函数,本段代码实现,字符串字符集转换。
jstring
MyNewString(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);
/* * 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; }