多语言展示
当前在线:1736今日阅读:2今日分享:38

android ndk jni 字符串 String jstring

在android ndk开发的过程中,经常会遇到字符串的问题,但是 jstring 这个类型又不同于一般的数组,那么String的具体的操作该怎么进行了?代码主要涉及:        ① UTF编码转换(一般情况下够用,由于系统提供接口,所以比较简单);        ② 其他编码格式转换;        方便他人亦是方便自己,如果觉得还行就点下右边的投票吧,这样可以帮助其他人更快的找到解决问题的方法;有疑问的也可留言哦, 谢谢!
工具/原料
1

windows 8.1 x64

2

android-ndk-r10c

UTF编码转换
2

jstring 转 uft 字符集: GetStringUTFLength 可以获取该jstring的长度,如:uftLength = env->GetStringUTFLength(jstring);注: Java里面的String并不是按照\0结束,并作为结束符,所以必须返回字符串的长度GetStringUTFChars 可以获取对应的转换后的内容,该函数的最后一个jboolean类型的参数传0就可以了,如:char* pcUtf = env->GetStringUTFChars(jstring, 0);ReleaseStringUTFChars 该函数负责释放GetStringUTFChars 返回的指针,如:env->ReleaseStringUTFChars(jstring, pcUtf);

3

utf 字符集转 jstring:NewStringUTF 通过这个函数一个就可以直接实现 utf 字符集转 jstring,如:env->NewStringUTF (uft);

其他编码须知
1

获取String类的方法的函数签名:① 系统的源码目录,找android.jar如我的是:'D:\Android\adt-bundle-windows-x86_64-20140702\sdk\platforms\android-19\android.jar'② 解压 android.jar 到目录 android 里面③ 打开cmd,cd到该目录如我的是“D:\Android\adt-bundle-windows-x86_64-20140702\sdk\platforms\android-19”④ 运行cmd指令:javap -classpath android -s java.lang.String

2

查询的结果如下图所示:  public byte[] getBytes(java.lang.String) throws java.io.UnsupportedEncodingException;   descriptor: (Ljava/lang/String;)[B

3

android上面支持的字符集有,如下图所示:注:该字符集必须以android源代码中的注释为主,不同的平台支持的字符集可能不相同;

4

String类构造函数的签名: public java.lang.String(byte[], java.lang.String) throws java.io.UnsupportedEncodingException;   descriptor: ([BLjava/lang/String;)V

其他编码转换
1

下面的这个函数是实现了 jstring 到 char 的转换;pEnv 为当前的环境变量;ppChars 为从jstring中获取到的最终的char数组,内存由函数内部开辟;pLength 为jstring的长度;jstr 为需要转换的jstring类型;szCharset 这里传字符集,“前期准备”部分有介绍注:① Java里面的String并不是按照\0结束,并作为结束符,所以必须返回字符串的长度② 该测试用例并没有做异常处理,使用者可以自行补充上;完整代码如下:int jstring2char(JNIEnv* pEnv, char** ppChars, int* pLength, jstring jstr, char* szCharset){ jclass clsString = pEnv->FindClass('java/lang/String'); jstring charset = pEnv->NewStringUTF(szCharset); jmethodID method = pEnv->GetMethodID(clsString, 'getBytes', '(Ljava/lang/String;)[B'); jbyteArray byteArray = (jbyteArray) pEnv->CallObjectMethod(jstr, method, charset); jsize nLength = pEnv->GetArrayLength(byteArray); jbyte* bytes = pEnv->GetByteArrayElements(byteArray, JNI_FALSE); *pLength = nLength;  *ppChars = (char*) malloc(nLength);  memcpy(*ppChars, bytes, nLength); pEnv->ReleaseByteArrayElements(byteArray, bytes, 0); pEnv->DeleteLocalRef(charset); return 1;}

2

下面的这个函数是实现了 char 到 jstring 的转换;完整的代码如下:jstring char2jstring(JNIEnv* pEnv, char* pChars, int Length, char* szCharset) { jclass clsString = pEnv->FindClass('java/lang/String'); /// 属于构造函数的范畴 jmethodID construct = pEnv->GetMethodID(clsString, '', '([BLjava/lang/String;)V'); jbyteArray byteArray = pEnv->NewByteArray(Length); pEnv->SetByteArrayRegion(byteArray, 0, Length, (jbyte*) pChars); jstring charset = pEnv->NewStringUTF(szCharset); jstring strDst = (jstring) pEnv->NewObject(clsString, construct, byteArray, charset); pEnv->DeleteLocalRef(byteArray); return strDst;}

3

下面是一个完整的测试用例,将java层传进来的 jstring 复制一份后重新传回去,完整的代码如下:JNIEXPORT jstring JNICALL Java_ndk_jniarray_MainActivity_swapString (JNIEnv *pEnv, jclass clsActivity, jstring src) {    char* pUtf = NULL;    int  nLength = 0;    jstring2char(pEnv, &pUtf, &nLength, src, 'UTF-8');      jstring dst = char2jstring(pEnv, pUtf, nLength, 'UTF-8');    free(pUtf);    return dst;}

4

方便他人亦是方便自己,如果觉得还行就点下下边的投票吧,这样可以帮助其他人更快的找到解决问题的方法;有疑问的也可留言哦, 谢谢!

推荐信息