以下方式 总归 还是在使用使用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,"", "([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
#include
#include
/*
* 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, "", "([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;
}