2014년 10월 27일 월요일

jstring to char* (JNI)

JSP 또는 자바에서 인자(파라미터)로 jstring을 받는다는 가정하에...

jstring을 char*로 바꾸는 방법은 아래 두가지가 있다.
char* jstringToChar(JNIEnv* env, jstring str)
{
 int length = (*env)->GetStringLength( env, str );
 const jchar* jcstr = (*env)->GetStringChars( env, str, 0 );
 char* rtn = (char*)malloc( length * 2 + 1 );
 int size = 0;
// size = WideCharToMultiByte( 0, 0, (unsigned short*) jcstr, length, rtn, (length*2 +1 ), NULL, NULL );
// if ( size <= 0 ) return NULL;
 size = wcstombs( rtn, (unsigned short*) jcstr, length );
 (*env)->ReleaseStringChars( env, str, jcstr );
 rtn[ size ] = 0;
 return rtn;
}

위 방법은 jstring이 유니코드이기 때문에, 메모리 할당시 char 길이의 두배로 메모리를 할당 받고 있다.

그 다음 wcstombs(또는 WideCharToMultiByte)를 통해, 유니코드를 멀티바이트로 변환하여, 리턴한다.

그런데, 일부 시스템(WAS 중에서 JEUS가 메모리 할당에 문제가 있다.)에서 malloc할 경우 문제가 발생한다. 아무래도 일정용량 이상 메모리 할당을 못하는 것 같은데, JEUS 세팅문제가 확실한 것 같다. 같은 JEUS를 쓰는 두 업체에 작업을 했는데, 한 곳에서는 위 방법이 됐지만, 한 곳에서는 되지 않았다.

그래서 메모리 할당을 하지 않는 방법을 찾고 있었는데...정말 간단하다.

char* jstringToChar(JNIEnv* env, jstring str)
{
 char* cDesc = strdup((*env)->GetStringUTFChars(env, str, 0));
// (*env)->ReleaseStringUTFChars(env, str, cDesc);

 return cDesc;
}

그냥 jstring이 받아서 strdup로 메모리를 만든 후 복사하는 것이다. 근데 왜 이건 되는지 의문이다. 어차피 메모리 할당은 마찬가지 일텐데...

위 함수의 메모리 해제는 함수를 사용하는 곳에서 직접 해줘야 한다.

댓글 없음: