- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 재능이의 돈버는 일기
- StresslessLife
- K_JIN2SM
- 소소한 일상
- My Life Style & Memory a Box
- Blog's generation
- 공감 스토리
- 취객의 프로그래밍 연구실
- Love Me
- Dream Archive
- 세상에 발자취를 남기다 by kongmingu
- hanglesoul
- 카마의 IT 초행길
- 느리게.
- 미친듯이 즐겨보자..
- Joo studio
- Gonna be insane
- 악 다 날아갔어!! 갇대밋! 왓더...
- xopowo05
- 맑은공기희망운동
- 엔지니어 독립운동
- 혁준 블로그
- Simple in Complex with Simple
- 무의식이 의식을 지배한다
드럼치는 프로그래머
[JNI/NDK] JNI(JAVA <-> C)에서 한글 사용 본문
자바는 유니코드를 쓰고, JNI는 UTF-8을 쓰구, C/C++환경에서는 KSC5601 바이트문자열을 쓰더군요. 황당 그자체였습니다.
하지만, 여기도 그렇고 다른곳에서도 한글해결을 위한 명확한 방법을 제시한곳이 없더군요.
그래서, 3일동안 끙끙되며 찾은 방법을 JNI를 공부하거나 구현하고자 하는분을 위해서 설명드리고자 합니다.
참고URL : http://www.grine.co.kr/computer/lang6101.htm => JNI에서 한글처리하는 코어를 가져온 사이트임다. 겨우 찾아냈죠. ^^*
컴파일 환경은 WinXP, JDK1.4.2.04로 했으며, C컴파일을 위해서 VisualC++을 이용했습니다.
간단히 설명하면(파일명을 Test.java과 Test.c)
javac Test.java
javah Test
cl -IC:\j2sdk1.4.2_04\include -IC:\j2sdk1.4.2_04\include\win32 -LD Test.c
java Test
입니다.
이제 소스설명입니다. 설명은 자바->C만 하겠습니다. C->자바도 소스는 같이 첨부할테니 보시면 금방 아실수 있습니다.
public class JavaToC
{
public native void sendtoc(String ar[]);
static
{
System.loadLibrary("JavaToC"); // 클래스명과 동일하게
}
public static void main(String[] args)
{
String ar[] = {"노무현","대통령","짱!!"}; // C로 넘길 String 객체
JavaToC a = new JavaToC();
a.sendtoc(ar); // C호출
}
}
간단하죠? 만약, 이 부분이 어려웠다면 자바도 모르는 제가 했을리 없겠죠.
이제는 C부분입니다. 자바보다는 쬐금 깁니다. 하지만, 직접 코딩하는 부분은 얼마없으니 걱정마시길...
#include <jni.h>
#include "JavaToC.h"
#include <stdio.h>
#include <string.h>
// ==> 여기부터 쭈~~~~욱 내려가서
char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes );
jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr);
jbyteArray javaGetBytes( JNIEnv *env, jstring str );
jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding );
jstring javaNewString( JNIEnv *env, jbyteArray javaBytes );
jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding );
static jclass class_String;
static jmethodID mid_getBytes, mid_getBytesEncoding;
static jmethodID mid_newString, mid_newStringEncoding;
char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes )
{
size_t len = (*env)->GetArrayLength(env, javaBytes);
jbyte *nativeBytes = (*env)->GetByteArrayElements(env, javaBytes, 0);
char *nativeStr = (char *)malloc(len+1);
strncpy( nativeStr, nativeBytes, len );
nativeStr[len] = '\0';
(*env)->ReleaseByteArrayElements(env, javaBytes, nativeBytes, JNI_ABORT);
return nativeStr;
}
/* C 문자열로부터 자바 바이트 배열을 생성하여 반환 */
jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr)
{
jbyteArray javaBytes;
int len = strlen( nativeStr );
javaBytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, javaBytes, 0, len, (jbyte *) nativeStr );
return javaBytes;
}
/* 자바 스트링을 디폴트 인코딩의 자바 바이트 배열로 변환.
* String 클래스의 getBytes() 메쏘드를 호출한다. */
jbyteArray javaGetBytes( JNIEnv *env, jstring str )
{
if ( mid_getBytes == 0 )
{
if ( class_String == 0 )
{
jclass cls = (*env)->FindClass(env, "java/lang/String");
if ( cls == 0 ) return 0; /* 오류 */
class_String = (*env)->NewGlobalRef(env, cls);
if ( class_String == 0 ) return 0; /* 오류 */
}
mid_getBytes = (*env)->GetMethodID(env, class_String, "getBytes", "()[B");
if (mid_getBytes == 0) return 0;
}
/* str.getBytes(); */
return (*env)->CallObjectMethod( env, str, mid_getBytes );
}
/* 자바 스트링을 지정된 인코딩 `encoding'의 자바 바이트 배열로 변환.
* String 클래스의 getBytes(String encoding) 메쏘드를 호출한다. */
jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding )
{
if ( mid_getBytesEncoding == 0 )
{
if ( class_String == 0 )
{
jclass cls = (*env)->FindClass(env, "java/lang/String");
if ( cls == 0 ) return 0; /* 오류 */
class_String = (*env)->NewGlobalRef(env, cls);
if ( class_String == 0 ) return 0; /* 오류 */
}
mid_getBytesEncoding = (*env)->GetMethodID(env, class_String, "getBytes", "(Ljava/lang/String;)[B");
if (mid_getBytesEncoding == 0) return 0;
}
/* str.getBytes( encoding ); */
return (*env)->CallObjectMethod(env, str, mid_getBytesEncoding, (*env)->NewStringUTF(env, encoding));
}
/* 디폴트 인코딩의 자바 바이트 배열을 자바 스트링으로 변환.
* String 클래스의 new String(byte[] bytes) 메쏘드를 호출한다. */
jstring javaNewString( JNIEnv *env, jbyteArray javaBytes )
{
if ( mid_newString == 0 )
{
if ( class_String == 0 )
{
jclass cls = (*env)->FindClass(env, "java/lang/String");
if ( cls == 0 ) return 0; /* 오류 */
class_String = (*env)->NewGlobalRef(env, cls);
if ( class_String == 0 ) return 0; /* 오류 */
}
mid_newString = (*env)->GetMethodID(env, class_String, "<init>", "([B)V");
if ( mid_newString == 0 ) return 0;
}
/* new String( javaBytes ); */
return (*env)->NewObject(env, class_String, mid_newString, javaBytes );
}
/* 지정된 인코딩 `encoding'의 자바 바이트 배열을 자바 스트링으로 변환.
* String 클래스의 new String(byte[] bytes, String encoding)
* 메쏘드를 호출한다. */
jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding )
{
int len;
jstring str;
if ( mid_newString == 0 )
{
if ( class_String == 0 )
{
jclass cls = (*env)->FindClass(env, "java/lang/String");
if ( cls == 0 ) return 0; /* 오류 */
class_String = (*env)->NewGlobalRef(env, cls);
if ( class_String == 0 ) return 0; /* 오류 */
}
mid_newString = (*env)->GetMethodID(env, class_String, "<init>", "([BLjava/lang/String;)V");
if ( mid_newString == 0 ) return 0;
}
/* new String( javaBytes, encoding ); */
str = (*env)->NewObject(env, class_String, mid_newString, javaBytes, (*env)->NewStringUTF(env, encoding) );
return str;
}
//<-- 이부분까지는 한글변환 함수들을 정의한것으로 그냥 붙여넣기한사용하시면 됩니다.
JNIEXPORT void JNICALL Java_JavaToC_sendtoc(JNIEnv *env, jobject obj, jobjectArray ar)
{
// 자바에서 넘긴 String객체는 jobjectArray ar가 받습니다.
int i;
char str[100];
jstring iArray
jint i1;
i1 = (*env)->GetArrayLength(env, ar); // 갯수 세기
for(i = 0; i < i1; i++) // 반복문
{
iArray = (jstring)(*env)->GetObjectArrayElement(env, ar, i); // 배열객체를 참조하기 위해서
str[0] = '\0';
strcpy(str, jbyteArray2cstr(env, javaGetBytes(env, iArray))); // i번째 배열객체를 읽어온 iArray를 문자열변환하여 str에 저장합니다.
printf("ar[%d] = %s\n", i, str); // 출력
}
return;
}
핫...간단하죠?
뭐...저도 찾는데 오래걸려서 그렇지 막상해보니 제가 직접 코딩한것은 거의 없군요.
JNI로 한글처리로 고민하는분들께 조금이나마 도움이 되었으면 좋겠습니다.
'★─Programing > ☆─JNI | NDK' 카테고리의 다른 글
[JNI/NDK] Cygwin을 설치가 계속 실패, 미러 사이트 주소는... (0) | 2013.04.19 |
---|---|
[JNI/NDK] Android JNI 에서 로그찍는법 (0) | 2013.04.19 |
[JNI/NDK] 안드로이드 java와 ndk의 속도 차이 (0) | 2013.04.17 |
[JNI/NDK] JNI 사용 (C, C++에서 Java Library 사용하기) (0) | 2013.04.17 |
[JNI/NDK] JNI Object(class, struct) argument passing (클래스 -> 구조체 변환) (0) | 2013.04.17 |