- 전체
- JAVA 일반
- JAVA 수학
- JAVA 그래픽
- JAVA 자료구조
- JAVA 인공지능
- JAVA 인터넷
- Java Framework
- Java GUI (AWT,SWING,SWT,JFACE)
- SWT and RCP (web RAP/RWT)[eclipse], EMF
[JNI] 안드로이드 JNI 환경에서 C++과 Java 간의 한글 데이터 전송 문제
2014.05.06 20:29
[JNI] 안드로이드 JNI 환경에서 C++과 Java 간의 한글 데이터 전송 문제
[출처] http://snowbora.tistory.com/371
지금은 잠깐 쉬고 있지만, 예전에 안드로이드 ndk 환경에서 프로그래밍을 하던 때가 있었습니다.
그 때, JNI 인터페이스를 통해 Native단의 C++과 Application단의 Java와의 데이터를 주고 받아야 하는 API들을
만들었었는데, 그 중 문자열 전송과 관련해서 한글이 죄다 깨져서 전송되는 현상이 있었습니다.
Java 단에서는 UTF-8 방식을 이용하고, C++에서는 KSC5601 방식의 문자열이었기 때문에 발생하는 문제였습니다.
그래서 구글링을 통해 C++과 Java간의 한글 변환 관련 코드를 확보 및 컨버팅을 했습니다.
C++과 Java간의 한글 변환 코드는 다음과 같습니다. 다음은 헤더 파일입니다.
그리고 다음은 C++ 소스 코드입니다.'
그 때, JNI 인터페이스를 통해 Native단의 C++과 Application단의 Java와의 데이터를 주고 받아야 하는 API들을
만들었었는데, 그 중 문자열 전송과 관련해서 한글이 죄다 깨져서 전송되는 현상이 있었습니다.
Java 단에서는 UTF-8 방식을 이용하고, C++에서는 KSC5601 방식의 문자열이었기 때문에 발생하는 문제였습니다.
그래서 구글링을 통해 C++과 Java간의 한글 변환 관련 코드를 확보 및 컨버팅을 했습니다.
C++과 Java간의 한글 변환 코드는 다음과 같습니다. 다음은 헤더 파일입니다.
01.#ifndef _STRING_CONVERTER_FOR_JNI_02.#define _STRING_CONVERTER_FOR_JNI_03. 04.#include <jni.h>05.#include <stdio.h>06.#include <string.h>07. 08.#ifdef __cplusplus09.extern "C"10.{11.#endif12. 13. char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes );14. jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr);15. jbyteArray javaGetBytes( JNIEnv *env, jstring str );16. jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding );17. jstring javaNewString( JNIEnv *env, jbyteArray javaBytes );18. jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding );19. 20. jstring javaNewStringChar(JNIEnv* env, const char* nativeStr);21. 22.#ifdef __cplusplus23.}24.#endif25. 26.#endif //_STRING_CONVERTER_FOR_JNI_27.</string.h></stdio.h></jni.h>그리고 다음은 C++ 소스 코드입니다.
001.#include "StringConverter_For_JNI.h"002. 003.static jclass class_String;004.static jmethodID mid_getBytes, mid_getBytesEncoding;005.static jmethodID mid_newString, mid_newStringEncoding;006. 007.char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes )008.{009. size_t len = env->GetArrayLength(javaBytes);010. jbyte *nativeBytes = env->GetByteArrayElements(javaBytes, 0);011. char *nativeStr = (char *)malloc(len+1);012. strncpy( nativeStr, (const char*)nativeBytes, len );013. nativeStr[len] = '[JNI] 안드로이드 JNI 환경에서 C++과 Java 간의 한글 데이터 전송 문제
[출처] http://snowbora.tistory.com/371
지금은 잠깐 쉬고 있지만, 예전에 안드로이드 ndk 환경에서 프로그래밍을 하던 때가 있었습니다.
그 때, JNI 인터페이스를 통해 Native단의 C++과 Application단의 Java와의 데이터를 주고 받아야 하는 API들을
만들었었는데, 그 중 문자열 전송과 관련해서 한글이 죄다 깨져서 전송되는 현상이 있었습니다.
Java 단에서는 UTF-8 방식을 이용하고, C++에서는 KSC5601 방식의 문자열이었기 때문에 발생하는 문제였습니다.
그래서 구글링을 통해 C++과 Java간의 한글 변환 관련 코드를 확보 및 컨버팅을 했습니다.
C++과 Java간의 한글 변환 코드는 다음과 같습니다. 다음은 헤더 파일입니다.
01.#ifndef _STRING_CONVERTER_FOR_JNI_02.#define _STRING_CONVERTER_FOR_JNI_03. 04.#include <jni.h>05.#include <stdio.h>06.#include <string.h>07. 08.#ifdef __cplusplus09.extern "C"10.{11.#endif12. 13. char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes );14. jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr);15. jbyteArray javaGetBytes( JNIEnv *env, jstring str );16. jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding );17. jstring javaNewString( JNIEnv *env, jbyteArray javaBytes );18. jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding );19. 20. jstring javaNewStringChar(JNIEnv* env, const char* nativeStr);21. 22.#ifdef __cplusplus23.}24.#endif25. 26.#endif //_STRING_CONVERTER_FOR_JNI_27.</string.h></stdio.h></jni.h>
그리고 다음은 C++ 소스 코드입니다. 001.#include "StringConverter_For_JNI.h"002. 003.static jclass class_String;004.static jmethodID mid_getBytes, mid_getBytesEncoding;005.static jmethodID mid_newString, mid_newStringEncoding;006. 007.char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes )008.{009. size_t len = env->GetArrayLength(javaBytes);010. jbyte *nativeBytes = env->GetByteArrayElements(javaBytes, 0);011. char *nativeStr = (char *)malloc(len+1);012. strncpy( nativeStr, (const char*)nativeBytes, len );013. nativeStr[len] = '\0';014. env->ReleaseByteArrayElements(javaBytes, nativeBytes, JNI_ABORT);015. 016. return nativeStr;017.}018. 019.jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr)020.{021. jbyteArray javaBytes;022. int len = strlen( nativeStr );023. javaBytes = env->NewByteArray(len);024. env->SetByteArrayRegion(javaBytes, 0, len, (jbyte *) nativeStr );025. 026. return javaBytes;027.}028. 029.jbyteArray javaGetBytes( JNIEnv *env, jstring str )030.{031. if ( mid_getBytes == 0 )032. {033. if ( class_String == 0 )034. {035. jclass cls = env->FindClass("java/lang/String");036. if ( cls == 0 )037. {038. return 0;039. }040. 041. class_String = (jclass)env->NewGlobalRef(cls);042. env->DeleteLocalRef(cls);043. if ( class_String == 0 )044. {045. return 0;046. }047. }048. 049. mid_getBytes = env->GetMethodID(class_String, "getBytes", "()[B");050. if (mid_getBytes == 0)051. {052. return 0;053. }054. }055. 056. return (jbyteArray)env->CallObjectMethod(str, mid_getBytes );057.}058. 059.jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding )060.{061. if ( mid_getBytesEncoding == 0 )062. {063. if ( class_String == 0 )064. {065. jclass cls = env->FindClass("java/lang/String");066. if ( cls == 0 )067. {068. return 0;069. }070. 071. class_String = (jclass)env->NewGlobalRef(cls);072. env->DeleteLocalRef(cls);073. if ( class_String == 0 )074. {075. return 0;076. }077. }078. 079. mid_getBytesEncoding = env->GetMethodID(class_String, "getBytes", "(Ljava/lang/String;)[B");080. if (mid_getBytesEncoding == 0)081. {082. return 0;083. }084. }085. 086. jstring jstr = env->NewStringUTF(encoding);087. jbyteArray retArray = (jbyteArray)env->CallObjectMethod(str, mid_getBytesEncoding, jstr);088. env->DeleteLocalRef(jstr);089. 090. return retArray;091.}092. 093.jstring javaNewString( JNIEnv *env, jbyteArray javaBytes )094.{095. if ( mid_newString == 0 )096. {097. if ( class_String == 0 )098. {099. jclass cls = env->FindClass("java/lang/String");100. if ( cls == 0 )101. {102. return 0;103. }104. 105. class_String = (jclass)env->NewGlobalRef(cls);106. env->DeleteLocalRef(cls);107. if ( class_String == 0 )108. {109. return 0;110. }111. }112. 113. mid_newString = env->GetMethodID(class_String, "<init>", "([B)V");114. if ( mid_newString == 0 )115. {116. return 0;117. }118. }119. 120. return (jstring)env->NewObject(class_String, mid_newString, javaBytes );121.}122. 123.jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding )124.{125. int len;126. jstring str;127. if ( mid_newString == 0 )128. {129. if ( class_String == 0 )130. {131. jclass cls = env->FindClass("java/lang/String");132. if ( cls == 0 )133. {134. return 0;135. }136. 137. class_String = (jclass)env->NewGlobalRef(cls);138. env->DeleteLocalRef(cls);139. if ( class_String == 0 )140. {141. return 0;142. }143. 144. }145. 146. mid_newString = env->GetMethodID(class_String, "<init>", "([BLjava/lang/String;)V");147. if ( mid_newString == 0 )148. {149. return 0;150. }151. }152. 153. jstring jstr = env->NewStringUTF(encoding);154. str = (jstring)env->NewObject(class_String, mid_newString, javaBytes, jstr);155. env->DeleteLocalRef(jstr);156. 157. return str;158.}159. 160.jstring javaNewStringChar(JNIEnv* env, const char* nativeStr)161.{162. jbyteArray byteArray = cstr2jbyteArray(env, nativeStr);163. jstring jstr = javaNewString(env, byteArray);164. env->DeleteLocalRef(byteArray);165. 166. return jstr;167.}168.</init></init>
이 함수들을 이용해서 실제로 사용한 예제는 다음과 같습니다.
C++의 string을 Java용 jstring으로 변환하는 부분 1.jstring jstrValue;2.jfieldID fieldID;3.jmethodID methodID;4. 5.methodID = env->GetMethodID( cProgramInfo, "ProgramName","(Ljava/lang/String;)V");6.jstrValue = javaNewStringChar(env, strProgramName);7.env->CallVoidMethod( jElement, methodID, jstrValue);8.env->DeleteLocalRef(jstrValue);
Java용 jstring를 C++의 string으로 변환하는 함수 01.string title_;02.jmethodID methodID;03. 04.methodID = env->GetMethodID( cProgramInfo, "ProgramTitle","()Ljava/lang/String;");05.jstring jstrTitle = (jstring)env->CallObjectMethod(jElement, methodID);06.if(jstrTitle)07.{08. pszTitle = (char*)env->GetStringUTFChars(jstrTitle, &iscopy);09. title_ = pszTitle;10. env->ReleaseStringUTFChars(jstrTitle, pszTitle);11. env->DeleteLocalRef(jstrTitle); 12.}
;014. env->ReleaseByteArrayElements(javaBytes, nativeBytes, JNI_ABORT);015. 016. return nativeStr;017.}018. 019.jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr)020.{021. jbyteArray javaBytes;022. int len = strlen( nativeStr );023. javaBytes = env->NewByteArray(len);024. env->SetByteArrayRegion(javaBytes, 0, len, (jbyte *) nativeStr );025. 026. return javaBytes;027.}028. 029.jbyteArray javaGetBytes( JNIEnv *env, jstring str )030.{031. if ( mid_getBytes == 0 )032. {033. if ( class_String == 0 )034. {035. jclass cls = env->FindClass("java/lang/String");036. if ( cls == 0 )037. {038. return 0;039. }040. 041. class_String = (jclass)env->NewGlobalRef(cls);042. env->DeleteLocalRef(cls);043. if ( class_String == 0 )044. {045. return 0;046. }047. }048. 049. mid_getBytes = env->GetMethodID(class_String, "getBytes", "()[B");050. if (mid_getBytes == 0)051. {052. return 0;053. }054. }055. 056. return (jbyteArray)env->CallObjectMethod(str, mid_getBytes );057.}058. 059.jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding )060.{061. if ( mid_getBytesEncoding == 0 )062. {063. if ( class_String == 0 )064. {065. jclass cls = env->FindClass("java/lang/String");066. if ( cls == 0 )067. {068. return 0;069. }070. 071. class_String = (jclass)env->NewGlobalRef(cls);072. env->DeleteLocalRef(cls);073. if ( class_String == 0 )074. {075. return 0;076. }077. }078. 079. mid_getBytesEncoding = env->GetMethodID(class_String, "getBytes", "(Ljava/lang/String;)[B");080. if (mid_getBytesEncoding == 0)081. {082. return 0;083. }084. }085. 086. jstring jstr = env->NewStringUTF(encoding);087. jbyteArray retArray = (jbyteArray)env->CallObjectMethod(str, mid_getBytesEncoding, jstr);088. env->DeleteLocalRef(jstr);089. 090. return retArray;091.}092. 093.jstring javaNewString( JNIEnv *env, jbyteArray javaBytes )094.{095. if ( mid_newString == 0 )096. {097. if ( class_String == 0 )098. {099. jclass cls = env->FindClass("java/lang/String");100. if ( cls == 0 )101. {102. return 0;103. }104. 105. class_String = (jclass)env->NewGlobalRef(cls);106. env->DeleteLocalRef(cls);107. if ( class_String == 0 )108. {109. return 0;110. }111. }112. 113. mid_newString = env->GetMethodID(class_String, "<init>", "([B)V");114. if ( mid_newString == 0 )115. {116. return 0;117. }118. }119. 120. return (jstring)env->NewObject(class_String, mid_newString, javaBytes );121.}122. 123.jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding )124.{125. int len;126. jstring str;127. if ( mid_newString == 0 )128. {129. if ( class_String == 0 )130. {131. jclass cls = env->FindClass("java/lang/String");132. if ( cls == 0 )133. {134. return 0;135. }136. 137. class_String = (jclass)env->NewGlobalRef(cls);138. env->DeleteLocalRef(cls);139. if ( class_String == 0 )140. {141. return 0;142. }143. 144. }145. 146. mid_newString = env->GetMethodID(class_String, "<init>", "([BLjava/lang/String;)V");147. if ( mid_newString == 0 )148. {149. return 0;150. }151. }152. 153. jstring jstr = env->NewStringUTF(encoding);154. str = (jstring)env->NewObject(class_String, mid_newString, javaBytes, jstr);155. env->DeleteLocalRef(jstr);156. 157. return str;158.}159. 160.jstring javaNewStringChar(JNIEnv* env, const char* nativeStr)161.{162. jbyteArray byteArray = cstr2jbyteArray(env, nativeStr);163. jstring jstr = javaNewString(env, byteArray);164. env->DeleteLocalRef(byteArray);165. 166. return jstr;167.}168.</init></init>이 함수들을 이용해서 실제로 사용한 예제는 다음과 같습니다.
C++의 string을 Java용 jstring으로 변환하는 부분
1.jstring jstrValue;2.jfieldID fieldID;3.jmethodID methodID;4. 5.methodID = env->GetMethodID( cProgramInfo, "ProgramName","(Ljava/lang/String;)V");6.jstrValue = javaNewStringChar(env, strProgramName);7.env->CallVoidMethod( jElement, methodID, jstrValue);8.env->DeleteLocalRef(jstrValue);Java용 jstring를 C++의 string으로 변환하는 함수
01.string title_;02.jmethodID methodID;03. 04.methodID = env->GetMethodID( cProgramInfo, "ProgramTitle","()Ljava/lang/String;");05.jstring jstrTitle = (jstring)env->CallObjectMethod(jElement, methodID);06.if(jstrTitle)07.{08. pszTitle = (char*)env->GetStringUTFChars(jstrTitle, &iscopy);09. title_ = pszTitle;10. env->ReleaseStringUTFChars(jstrTitle, pszTitle);11. env->DeleteLocalRef(jstrTitle); 12.}본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.

