2011-02-22 8 views
1

UChar * (즉, 유니 코드 문자 배열)을 반환하는 JNI를 통해 ICU4C 함수에 액세스하고 있습니다. UChar 배열의 각 멤버를 a로 변환하여 jbyteArray로 변환 할 수있었습니다. 내가 만든 로컬 jbyte [] 배열을 env-> SetByteArrayRegion() 함수를 사용하여 Java 반환했습니다 ... 이제 Java에서 Byte [] 배열을 가지고 있지만 모든 횡설수설이 있습니다 .. 기껏해야 이상한 기호. .. 어디에 문제가 있을지 모르겠다 ... 문제가 있다면 유니 코드 문자로 작업하고있다 ... 바이트 [] Java로 제대로 char [] 어떻게 변환합니까? 뭔가 여기에 코드 조각입니다 ... 바로 매핑되지 않는 :ICU4C 바이트를 Java 문자로 변환


--- JNI 코드 (그것은 짧게하는 경미한 변경) ---

static jint testFunction(JNIEnv* env, jclass c, jcharArray srcArray, jbyteArray destArray) { 

    jchar* src = env->GetCharArrayElements(srcArray, NULL); 
    int n = env->getArrayLength(srcArray); 

    UChar *testStr = new UChar[n]; 
    jbyte destChr[n]; 

    //calling ICU4C function here  
    icu_function (src, testStr); //takes source characters and returns UChar* 

    for (int i=0; i<n; i++) 
     destChr[i] = testStr[i]; //is this correct? 

    delete testStr; 
    env->SetByteArrayRegion(destArray, 0, n, destChr); 
    env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT); 

    return (n); //anything for now 
} 

이 - 자바 코드 - 문자열 wohoo = "ABCD bal bla bla"; char [] myChars = wohoo.toCharArray();

byte[] myICUBytes = new byte[myChars.length]; 
int value = MyClass.testFunction (myChars, myICUBytes); 

System.out.println(new String(myICUBytes)) ;// produces gibberish & weird symbols 

가 나는 또한 시도 :에서 System.out.println (새로운 String (myICUBytes을 Charset.forName는 ("UTF-16")))과 마찬가지로 gebberishy입니다 ....

ICU 함수가 UChar *에서 올바른 유니 코드 문자를 반환한다는 점에 유의하십시오. ... jbyteArray와 Java 로의 변환 사이의 어딘가에 ...

Help!

+0

동일한 질문을 두 번 질문하지 마십시오. 귀하의 문제가 이미 (명백하게) 해결되었음을 확인하기 위해 다른 사본에 상당한 시간을 할애했습니다. –

답변

1
destChr[i] = testStr[i]; //is this correct? 

괜찮은 것처럼 보입니다.

JNI types :

byte jbyte signed 8 bits 
char jchar unsigned 16 bits 

ICU4C types :

즉 16 비트 폭의 경우는 UCHAR wchar_t를 정의 할; 항상 인 것으로 가정합니다. wchar_t를 16 비트 없으면 GCC> = 4.4 UTF16 문자열 리터럴을 처리 할 수 ​​있기 때문에

넓은 다음 UCHAR uint16_t이되도록 정의하거나 char16_t. 이로 인해 UChar 플랫폼 정의에 종속적 인 이되지만 직접 문자열 유형 은 플랫폼과 호환되며 16 비트 wchar_t 유형을 사용할 수 있습니다.

그렇기 때문에 icu_function이 수행하는 것과는 별도로, 16 비트 값을 8 비트 너비 유형에 맞추려고합니다.

자바 바이트 배열을 사용해야하는 경우 유니 코드 인코딩으로 트랜스 코딩하여 8 비트 char 유형으로 변환하는 것이 좋습니다.

some C code 의역하려면, 당신은 다음 new String(myICUBytes, "UTF-8")을 사용하여 Java 문자열이 트랜스 코딩 할 수

UChar *utf16 = (UChar*) malloc(len16 * sizeof(UChar)); 
//TODO: fill data 
// convert to UTF-8 
UConverter *encoding = ucnv_open("UTF-8", &status); 
int len8 = ucnv_fromUChars(encoding, NULL, 0, utf16, len16, &status); 
char *utf8 = (char*) malloc(len8 * sizeof(char)); 
ucnv_fromUChars(encoding, utf8, len8, utf16, len16, &status); 
ucnv_close(encoding); 
//TODO: char to jbyte 

.

이미 샘플 코드에 있었기 때문에 UTF-8을 사용 했으므로 엔디안에 대해 걱정할 필요가 없습니다. 내 C를 C++로 적절하게 변환하십시오.

+0

감사합니다 !!! 그건 의미가 있습니다. jcharArray로 모든 것을 바꿨고 모든 것이 이제 작동합니다. p.s : 나는 당신에게 엄지 손가락을주기에 충분한 명성을 얻지 못했지만, 내가 가진만큼 빨리 할 것이다 :) 새로운 사용자가 여기있다. – Ayyoudy

0

ICU4J 사용을 고려 했습니까?

또한 바이트를 문자열로 변환 할 때 문자 인코딩을 지정해야합니다. 문제의 도서관에 익숙하지 않아서 더 이상 조언 할 수 없지만 아마도 "UTF-16"또는 유사 할 것입니까?

아, 또한 인쇄하려는 터미널이 올바른 문자 세트를 사용하지 않고 있거나 사용할 수있는 올바른 글리프가 없기 때문에 단순히 표시 오류가 발생할 수 있습니다.

+0

ICU4J는 크기 (5MB +)로 인해 옵션이 아니며 이미 프로젝트에 ICU4C 및 JNI 통합이 있습니다. 그러나 ICu4J를 사용해 보았지만 제대로 작동했지만 JNI와 ICU4C를 사용하여 동일한 결과를 얻으려고합니다. – Ayyoudy

+0

터미널 문제와 관련해서는 ... ICU4J를 사용해 보았을 때 잘 작동하므로 고려해 보았습니다. 글리프가 거기에 있습니다. – Ayyoudy

관련 문제