[질문] 자바에서 C라이브러리 사용시 한글 문제
--------- 자바 소스 (Linux) --------------------------------------------------------
public class sdt{
static{
System.loadLibrary("sdtdll");
}
public native String cfunction(String IN);
public static void main(String[] args) throws Exception{
String idata = "한글";
String odata = new sdt().cfunction(idata);
System.out.println("java : idata [" + idata + "]");
System.out.println("java : odata [" + odata + "]"); // <------- 한글깨짐
}
}
---------- C 소스 (Linux GCC) ----------------------------------------------------
JNIEXPORT jstring JNICALL Java_sdt_cfunction (JNIEnv *env, jobject obj, jstring IDATA)
{
const char *idata = NULL;
char *Result = "한글";
idata = (*env)->GetStringUTFChars(env, IDATA, 0);
printf("clib : idata [%d][%s]\n", strlen(idata), idata); // <------ 한글깨짐
(*env)->ReleaseStringUTFChars(env, IDATA, idata);
return (*env)->NewStringUTF(env, Result);
}
-------------------------------------------------------------------------------------
소스는 위와 같습니다.
자바에서 C 로 짠 런타임 라이블러리를 호출하고 리턴값을 받는 프로그램입니다.
위와 같이 한글깨짐을 방지하거나 보정하는 방법을 알려주시면 감사하겠습니다.
항상 많은 도움을 받아 감사하게 생각하며~~~ 좋은 하루 되세요....
자바는 시스템분류에서(Virtual Machine) Linux와 동급머신
자바는 시스템분류에서(Virtual Machine) Linux와 동급머신으로 간주해야 합니다. 리눅스에서 자바를 돌린다고 해도(위와같이 JNI를 호출한다고 할때) 리눅스 운영체제상의 프로그램과 자바운영체제상의 프로그램과 IPC한다고 간주해야합니다.
서로다른 시스템간의 데이터전송을 수행한다고 본다는 얘기지요.
리눅스에서 locale을 수행해서 현재의 인코딩을 보세요.
자바의 locale은 무엇일까요? unicode-32 Big endian입니다.
잠시, 윈도우는? unicode-32 little enian입니다.
만일, 자바에서 한글을 리눅스 C로 보낸다면, 리눅스 C로의 전송은 unicode 32 Big Endian이겠지요. C에서 이를 출력하면? 아~ 리눅스의 locale이 unicode 32 BE가 아닐것이므로 당근... 글씨가 깨지겠지요.
반면, 리눅스 C에서 '한글'을 하드코딩한후 자바로 그냥 보내면? 자바입장에서는 unicode-32 BE으로 해당 글자를 인지할것이고(사실 다른 코드일텐데), 그냥 출력시 이상한(?) 출력이 되겠습니다.
방법은? 코드를 바꾸는것이지요. 마치 little endian, Big endian시스템들이
혼재되어 있는 시스템들간에 바이너리 데이터를 원할하게 전송하기 위해
Network byte order를 만들고 이로 바꿔서 주고/받고 하듯이 말입니다.
이러한 시스템코드간의 문제를 통합해결해놓은 iconv를 C에서 사용해서 자바의 비위를 맞춰주는게 어떨까?라고 권하고 싶습니다.
libiconv라이브러리를 사용하면 되겠지요. 테스트는 이 라이브러리로 만든 iconv유틸리티를 통해서 좀 해보고말입니다.
댓글 달기