2012-03-29 2 views
1

JNI를 사용하여 Java 프로그램과 C++ 함수 간의 인터페이스를 사용하고 있습니다. C++ 함수는 멀티 바이트 문자열을 처리합니다 (CP 1252). 나는 몇 가지 높은 순서 문자가없는 한JNI : Java String을 Code로 변환 Page 1252

char *arg=(char*) jEnv->GetStringUTFChars(jArg2,0); 

이 잘 작동 : 나는 문자 *로 자바 문자열을 변환하려면이 C++ 코드를 사용합니다. 예를 들어, 내 입력 인 경우

앨런 : I가 생성 인수가 있음을 알 수

(UTF C2 6C 61 6E 20 4A 6 층 6E 65 7E)

C3 82 6C 61 6E

, 나는보고 기대 :

C0, 내가 유니 코드 문자열을 얻는 시도 GetStringUTFChars에()가 UTF 문자열을 반환하도록되어 있다는보고도 6c 61 (e)

GetStringChars와() 및 WideCharToMultiByte는 통해 변환() :

const jchar *str=jEnv->GetStringChars(jArg2,0); 
WideCharToMultiByte(CP_UTF8,0,(LPCWSTR) str,jEnv->GetStringLength(jArg2),str,szStr,0,0); 

(당신은 내가 str을 할당하고 적절하게 szStr을 설정 한 것으로 가정 할 수있다). 이러한 상황에서, I은 생성 된 STR이 참조 : I가 WideCharToMultiByte는 첫 번째 매개 변수에 대한 다른 CP_ 값을 시도한 82 6C 61 6E

C3, 없음 수율 유용한 결과 (그들 중 위를 반환하거나 대체 a를 'A'에 대한

어떻게 든 나는이 결과 str을 얻을 수 있다는 기대 '?'.

C0 6C 61 (e)

그러나 지금까지 내가 운이 없었습니다.

답변

3

Java는 수정 된 버전의 UTF-8을 사용합니다. 여기에 자바의 문서에서 인용은 다음과 같습니다

UTF-8은 자바 플랫폼에 새로운 것이 아니다 수정 만가 보조 문자를 포함 할 수 있습니다 텍스트를 변환 할 때 해당 응용 프로그램 개발자가 더 잘 인식 할 필요가 뭔가 및 UTF-8에서. 기억해야 할 점은 일부 J2SE 인터페이스는 UTF-8과 비슷하지만 호환되지 않는 인코딩을 사용한다는 것입니다. 이 인코딩은 과거에는 "Java modified UTF-8" 또는 (잘못) "UTF-8"으로 불리는 경우가있었습니다. J2SE 5의 경우.0이면 문서는 이 "수정 된 UTF-8"이라고 통일되도록 업데이트됩니다.

수정 된 UTF-8과 표준 UTF-8 간의 비 호환성으로 인해 두 가지 차이점이 있습니다. . 먼저 수정 된 UTF-8은 U + 0000을 2 바이트 시퀀스 0xC0 0x80으로 표시하지만 표준 UTF-8은 단일 바이트 값 0x0을 사용합니다. 두 번째, 수정 된 UTF-8은 두 개의 서로 다른 코드 UTF-16 표현을 별도로 인코딩하여 보조 문자 을 나타냅니다. 대리 코드 유닛 ()의 각각은 총 6 바이트에 대해 3 바이트로 표현된다. 표준 UTF-8은 완전한 문자 인 에 대해 단일 4 바이트 시퀀스를 사용합니다.

UTF-8은 자바 가상 머신에 의해 사용되는 수정에 연결된 인터페이스 (예를 들면 자바 네이티브 인터페이스, 다양한 도구 인터페이스, 또는 Java 클래스 파일 등) java.io.DataInput의, 그리고 DataOutput 인터페이스 및이를 구현하거나 사용하는 클래스, 직렬화의 경우. Java Native Interface는 이 수정 된 UTF-8로 변환되는 루틴을 제공합니다. 반대로 표준 UTF-8은 String 클래스에서 java.io.InputStreamReader 및 OutputStreamWriter 클래스, java.nio.charset 기능 및 많은 API를 계층 적으로 지원합니다.

수정 된 UTF-8은 표준 UTF-8과 호환되지 않으므로 은 다른 하나가 필요없는 곳에서는 사용하지 않는 것이 중요합니다. 수정 된 UTF-8은 만 위에서 설명한 Java 인터페이스와 함께 사용할 수 있습니다. 다른 모든 경우, 특히 에서 가져온 데이터 스트림이 Java 플랫폼을 기반으로하지 않는 소프트웨어에 의해 해석되는 경우에는 표준 UTF-8을 사용해야합니다. 표준 UTF-8 이 필요한 경우 이 수정 된 UTF-8로 변환하는 Java 기본 인터페이스 루틴을 사용할 수 없습니다.

바이트 시퀀스 c2 6c 61 6e 20 4a 6f 6e 65 7e은 표준 UTF-8에서는 유효하지 않습니다. cp1252에서 동일한 바이트 시퀀스는 Âlan Jone~ 문자열입니다 (À 대신에 Â 고지). 표준 UTF-8에서

는 문자열 Àlan Jone~ 바이트 순서 c3 80 6c 61 6e 20 4a 6f 6e 65 7e ( c3 80 6c 대신 c2 6c 통지) 할 것이다.

모든 Java 문자열은 기본적으로 UTF-16이므로이 문자열을 UTF-8로 다시 가져올 필요가 없습니다. GetStringChars()을 사용하여 원래 UTF-16 인코딩 된 문자를 가져 와서 그대로 코드 페이지로 1252을 지정하는 WideCharToMultiByte()으로 전달합니다 (예에서 UTF-16 입력 버퍼와 cp1252 출력 버퍼 모두에 str을 사용하고 있습니다. t는 당신의 변수 혼란 얻을), 예!

const jchar *str = jEnv->GetStringChars(jArg2,0); 
char *cp1252 = NULL; 
int len = WideCharToMultiByte(1252, 0, (LPCWSTR)str, jEnv->GetStringLength(jArg2), NULL, 0, 0, 0); 
if (len > 0) 
{ 
    cp1252 = new char[len + 1]; 
    WideCharToMultiByte(1252, 0, (LPCWSTR)str, jEnv->GetStringLength(jArg2), cp1252, len, 0, 0); 
    cp1252[len] = 0; 
} 
+0

철저한 응답 주셔서 감사합니다. str은 잘라 내기/붙여 넣기 실수였습니다. 실제로 테스트에서 정확했습니다. WideCharToMultiByte에 대한 첫 번째 매개 변수가 실제 코드 페이지가 될 수 있다는 것을 깨닫지 못했습니다. 단, 문서에 나열된 정의 만 허용되었습니다. –

+0

다음 번에는 설명서를 더 자세히 읽어보십시오. http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx : "이 매개 변수는 운영 체제에 설치되거나 사용 가능한 모든 코드 페이지 값으로 설정할 수 있습니다 ... 응용 프로그램은 다음 표에 표시된 값 중 하나를 지정할 수도 있습니다 ..." –

0

코드 페이지 1252, Windows ANSI Western은 ISO Latin 1의 상위 집합이며 유니 코드의 하위 집합입니다. 따라서 유로 기호 및 기타 Microsoft 문자를 추가하지 않고도 살 수있는 경우 유니 코드 코드 포인트를 255 이상으로 버리면 유효한 cp 1252 인코딩 문자열이 생깁니다.

WideCharToMultiByte을 올바르게 사용하려면 (예 : 유로화 지원과 같은 일반적인 변환) 문서을 읽고 메모하십시오. 플래그 치

우리가 유즈넷에 대해 다른 사람들이 자신의 문서를 읽고 무엇이 중요하고 그렇지 않은지 알려주고 싶다고 말했던 것처럼, RTFM을하시기 바랍니다.

+0

는 사실 내가이 문제를 해결하기 위해 노력하는 두 기능에 RTFM'd, 난 그냥 매개 변수 (1)가 실제로 코드 페이지 만이 아니라 CP_ *을 정의 할 수 있다는 부분을 놓친 . –

관련 문제