jni 处理字符串乱码问题

在Android5.0的系统和Android5.0一下的系统,在字符串处理过程中有着许多的问题。我在处理过程中就碰到了,所以在这里总结一下。

1.从Java->c++字符串的处理。

第一种方式:

int getStringUTF(jstring str, char* pBuf, int bufLen)
{
	if (str == NULL || pBuf == NULL || bufLen <= 0)
		return -1;
	int sLen = m_pEnv->GetStringUTFLength(str);
	if (sLen == bufLen) {
		m_pEnv->GetStringUTFRegion(str, 0, sLen, pBuf);
	} else {
		char tmpBuf[sLen];
		m_pEnv->GetStringUTFRegion(str, 0, sLen, tmpBuf);
		tmpBuf[sLen] = '\0';
		strncpy(pBuf, tmpBuf, bufLen);
	}
	return strlen(pBuf);
}

int getJStringField(JNIEnv* env, jobject obj, const char* fieldName, char* pBuf, int len) 
{ 
      jclass cls = env->GetObjectClass(obj);
      jfieldID fid = env->GetFieldID(cls, fieldName, "Ljava/lang/String;");
       if (fid != NULL) 
      { 
          jstring jstr = (jstring)env->GetObjectField(obj, fid); 
         /* Null string object */ 
           if (jstr == NULL) 
           {
                /* Delete local reference */ 
                env->DeleteLocalRef(cls); 
                return -1; 
           }
           return getStringUTF(jstr,pBuf,len); 
        } 
      /* Delete local reference */ 
      env->DeleteLocalRef(cls);
       return -1; 
}

在这里,pBuf传入的为一个char []的格式,在两个系统中,字符串的大小jni这里会要求你处理的刚刚好。不然字符串获得的数据就会出错。

然后用第二种方式,就没有这种问题。

const char * getJStringField(JNIEnv* env,jobject obj, const char* fieldName)
{
	jclass cls = env->GetObjectClass(obj);

	jfieldID fid = env->GetFieldID(cls,fieldName,"Ljava/lang/String;");

	jstring str = (jstring)env->GetObjectField(obj, fid);

	jboolean b = true;

	return env->GetStringUTFChars(str,&b);
}
这里把字符串返回为char * 的字符。能够正确的返回数据。虽然在最后面会有乱码。


2.从c++->Java字符串处理。

第一种方式:

jstring createJString(JNIEnv* env,const char* text)
{
	if (text == NULL)
		return NULL;
	jstring temp = env->NewStringUTF(text);
	return temp;
}
这种方式太简单了。数据有错误的情况下容易导致程序奔溃。

第二种方式:

jstring createJStringCode(JNIEnv* env,const char* pat, const char * font)
{
	jclass strClass = env->FindClass("java/lang/String");
	jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
	jbyteArray bytes = env->NewByteArray(strlen(pat));
	env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
	jstring encoding = env->NewStringUTF(font);
	return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}
这种方式在调用的时候,第一个传入需要传递的char*,第二个传入编码格式比如:bgk,utf-8,big5等

在第二种方式中,也会产生出乱码的情况。

所以使用第二种情况的时候,必须要知道该字符串的编码格式是什么,不然就会产生出乱码,但是不会使程序奔溃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值