15

char* を jbyteArray に変換してから、java String のコンストラクターを呼び出して jstring を生成する必要がありますか? 他にどのように行うことができますか?助けてください。

static int testhandler(void *arg, ...)
 {
    int i;
    struct callback *cb = (struct callback *)arg;

    JNIEnv *env = cb->env;
    char *sig = cb->signature;

    jint size = (jint) strlen(sig);
    jint size1;
    va_list arguments;

    jobjectArray return_array;
    jclass obj_class;
    jbyteArray bytes;
    jstring str;

    obj_class = (*env)->FindClass(env, "java/lang/Object");
    return_array = (*env)->NewObjectArray(env, size, obj_class, NULL);

    va_start(arguments, arg);

    for (i = 0; i < size; i++) {
        jclass clazz;
        jmethodID id;
        jobject obj;
        jobject encoding;
        switch (sig[i]) {
            case 'i': {
                clazz = (*env)->FindClass(env, "java/lang/Integer");
                id = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
                obj = (*env)->NewObject(env, clazz, id, va_arg(arguments, uint32_t));
                (*env)->SetObjectArrayElement(env, return_array, i, obj);
                break;
            }
            case 'l': {
                clazz = (*env)->FindClass(env, "java/lang/Long");
                id = (*env)->GetMethodID(env, clazz, "<init>", "(J)V");
                obj = (*env)->NewObject(env, clazz, id, va_arg(arguments, uint64_t));
                (*env)->SetObjectArrayElement(env, return_array, i, obj);
                break;
            }
            case 's': {
                clazz = (*env)->FindClass(env, "java/lang/String");
                size1 = (jint) strlen(va_arg(arguments, char *));
                id = (*env)->GetMethodID(env, clazz, "<init>", "([BLjava/lang/String;)V");

                encoding = (*env)->NewStringUTF(env, va_arg(arguments, char *)); 
                bytes = (*env)->NewByteArray(env, size1); 
                (*env)->SetByteArrayRegion(env, bytes, 0, size1, (jbyte *)(va_arg(arguments, char *)));

                str = (jstring)(*env)->NewObject(env, clazz, id , bytes);
                obj = (*env)->NewObject(env, clazz, id, str);
                (*env)->SetObjectArrayElement(env, return_array, i, obj);
                break;
            }
            default: {
                printf("unknown signature char '%c'\n", sig[i]);
            }
        }

    }
    va_end(arguments);
    (*env)->CallVoidMethod(env, cb->handler, cb->id, return_array);

    return 0;
}
4

3 に答える 3

41

JNI APIのドキュメントを確認するだけです。例ここ
見つけるだろう:

jstring NewStringUTF(JNIEnv *env, const char *bytes);

したがって、次のようにする必要があります。

char *buf = (char*)malloc(10);
strcpy(buf, "123456789"); // with the null terminator the string adds up to 10 bytes
jstring jstrBuf = (*env)->NewStringUTF(env, buf);
于 2013-06-05T12:09:02.363 に答える
8

それはあなたの文字列の性質に依存しchar *ます。Unicode 文字の0 で終わる、変更された UTF-8エンコーディング NewStringUTFからのコピー。カウントされた Unicode 文字の UTF-16エンコーディングからのコピー。どちらも持っていない場合は、変換を実行する必要があります。NewString

を使用する多くのコードNewStringUTFは、文字列がNUL で終了する ASCIIであるという前提で書かれています。その仮定が正しければ、変更された UTF-8 エンコーディングと ASCII エンコーディングは同じバイト シーケンスを生成するため、機能します。そのようなコードは、文字列データの制限を文書化するために明確にコメントする必要があります。

あなたがほのめかしている変換方法—Java関数の呼び出し(例:String(byte[] bytes, Charset charset))—は良いものです。1つの代替手段(Windowsでは、Visual Studioを使用しているようです)はMultiByteToWideCharです。もう 1 つの代替手段は iconv です。

結論: 文字列が使用する文字セットとエンコーディングを把握し、それを UTF-16 でエンコードされた Unicode に変換して Java 文字列として使用する必要があります。

于 2013-06-05T17:02:39.770 に答える
3

Javaの UTF 文字列と C 文字列の違いによるものbyte[]ではなく、Javaに戻った方がよいでしょう。Java でエンコードの問題を処理する方がはるかに簡単です。jstring

Javaで:

byte[] otherString = nativeMethod("javastring".getBytes("UTF-8"))

C++ で:

jbyte* javaStringByte = env->GetByteArrayElements(javaStringByteArray, NULL);
jsize javaStringlen = env->GetArrayLength(javaStringByteArray);
std::vector<char> vjavaString;
vjavaString.assign(javaStringByte , javaStringByte + tokenlen);
std::string cString(vjavaString.begin(), vjavaString.end());
//
// do your stuff ..
//
jsize otherLen = otherCString.size();
jbyteArray otherJavaString = env->NewByteArray(otherLen);
env->SetByteArrayRegion(otherJavaString , 0, otherLen , (jbyte*) &otherJavaString [0]);

env->ReleaseByteArrayElements(javaStringByteArray, javaStringByte , JNI_ABORT);
return otherJavaString ;

再びJavaで:

new String(otherString);
于 2014-05-09T03:44:11.180 に答える