jni中的字符编码问题

    以前在使用jni中,发现jni字符问题,另外jni还存在着线程的不安全性,着实感觉jni不怎么地,但是目前没有好的jni的替代方案,这次介绍的是jni字符编码问题中需要注意的一个问题。

    一般我们使用的是utf8字符编码,在确认是utf8编码的同时,我们从java字串传递到c/c++库的字串是有个一个标准的接收过程,这个过程我们暂且称之为:编码传递
    编码传递是将jstring类型转换为char *或者const char*类型,其中在转换的过程中,需要有对字符编码的处理:

JNIEXPORT void JNICALL Java_com_alibaba_judystore_JudyStoreClient_modify(JNIEnv *env, jobject obj, jstring string, jboolean isOffer)
{
    const char *key = env->GetStringUTFChars(string, 0);
    jsClient->modify(key, isOffer);
    env->ReleaseStringUTFChars(string, key);
}
上面使用了jni内置的GetStringUTFChars来接收jstring,然后返回一个const char*类型,值得注意的是,这个这个指针分配的内存需要以ReleaseStringUTFChars方式释放,而不是delete和free。
    另外,有一种jni的方式是读取本地的字符串,见文件:jniutils.h,其中:
char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr)
{
    jbyteArray bytes = 0;
    char *result = 0;
    jthrowable exc;

    if (env->EnsureLocalCapacity(2) < 0)
    {
        return 0; /* out of memory error */
    }

    if (!MID_String_getBytes)
        MID_String_getBytes = env->GetMethodID(env->FindClass(
                "java/lang/String"), "getBytes", "()[B");

    bytes = (jbyteArray) env->CallObjectMethod(jstr, MID_String_getBytes);
    exc = env->ExceptionOccurred();

    if (!exc)
    {
        jint len = env->GetArrayLength(bytes);
        result = new char[len + 1];
        if (result == 0)
        {
            JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
            env->DeleteLocalRef(bytes);
            return 0;
        }

        env->GetByteArrayRegion(bytes, 0, len, (jbyte *) result);
        result[len] = 0; /* NULL-terminate */
    }
    else
    {
        env->DeleteLocalRef(exc);
    }

    env->DeleteLocalRef(bytes);

    return result;
}
然后使用JNU_GetStringNativeChars来调用:
JNIEXPORT jstring JNICALL Java_com_alibaba_offer_OfferClassifierJNI_nativeClassify
  (JNIEnv *env, jobject, jstring jstr)
{
    char *cstr = JNU_GetStringNativeChars(env, jstr);
    string str = string(cstr);
    double score;
    string category = classifier->classify(str, score);
    delete cstr;
    return env->NewStringUTF(category.c_str());
}
这样,会造成如果当前环境(locale)不是UTF-8,会造成编码传递失效,导致不可预料的错误。

Categories

,
| | 评论(0)

发表评论

August 2012

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

关于此日记

此日记由 Cnangel 发表于 June 21, 2009 12:00 PM

此Blog上的上一篇日记Pidgin and Yahoo (1)

此Blog上的下一篇日记Pidgin and Yahoo (2)

首页归档页可以看到最新的日记和所有日记。

归档

Powered by Movable Type 5.14-en