관리 메뉴

드럼치는 프로그래머

[JNI/NDK] JNI 사용 (C, C++에서 Java Library 사용하기) 본문

★─Programing/☆─JNI | NDK

[JNI/NDK] JNI 사용 (C, C++에서 Java Library 사용하기)

드럼치는한동이 2013. 4. 17. 09:58

JNI 하면 C++ 라이브러리를 JAVA에서 사용하는 것만 있는 줄 알았는데, 그 반대의 경우도 있다.
허나, 사용할 때 상당히 삽질을 많이해서, 사용기를 적어둔다.

1. 초기화

JavaVMOption options[2];
JavaVMInitArgs vm_args;
long status;

//참조할 jar, class 파일의 위치를 지정한다. 이게 잘못되면 추후에 NewObject 함수를 이용하여 클래스를 선언, 객체화 할 때, null을 반환한다. 따라서 이런 case에는 아래 경로가 확실히 지정되었는지를 보면 된다.
options[0].optionString = "-Djava.class.path=K:/lib/ant.jar;\
K:/optional.jar;K:/java-getopt.jar";

memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
// JavaVM create & JVM environment setting end
if(status == JNI_ERR)
{
     cerr << "JNI Start failed!!" << endl;
     exit(1);
}

2. 클래스 선언 및 라이브러리 함수 호출

vector<string> vecRet;

// JavaVM create & JVM environment setting start
cout<<"JVM Operating......."<<endl;
jclass cls;
jmethodID mid;
jobject obj;
jobjectArray retStr;
int staticresult=0;
int result=0;

// 사용할 클래스의 이름을 인자로 주어 클래스를 선언한다.
cls = env->FindClass("jniAPI");

if(cls != 0)
{
     cout<<"Find the class!" << endl;

     //생성자 함수를 찾아 참조할수 있도록 한다.
     //GetMethodID에서 두번째 인자를 "<init>"으로 하면 생성자를 호출한다.
     //세번째인자에서 () 안에는 argument를, ()뒤에는 함수의 return type을 지정한다.
     //각 타입은 첨부한 pdf 파일을 참고(JNI.pdf)한다
     jmethodID cls_constructor = env->GetMethodID(cls, "<init>", "()V");

     if (cls_constructor != 0) {
          //클래스를 생성한다. 뭔가 문제가 있으면 NULL을 반환한다. 생성자 함수의 변수 지정을 잘못했거나,

          // jar나 class 파일 import가 제대로 되었는지를 체크하자
         obj = env->NewObject(cls, cls_constructor, "()V");
         if(obj)
             cout<<"함수 호출 시작" << endl;
         else
             return vecRet;

         //extract란 이름의 함수를 호출할수 있도록 reference를 얻는다
         mid = env->GetMethodID(cls, "extract", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");

         if (mid != 0)
         {
               jstring arg1 = env->NewStringUTF(url); 

        //java에서는 euc-kr을 못 받는다. 따라서 한글이 포함되었다면 icov 등을 이용하여 utf-8로 변환해서 전달
             char sbuf[512];
             strcpy(sbuf,model_name);
             char sbuf2[512];
             IconvString("euckr","utf-8",sbuf,sbuf2);
             jstring arg2 = env->NewStringUTF(sbuf2);

             jobjectArray ar = (jobjectArray) env->CallObjectMethod(obj, mid, arg1,arg2);
             if(ar == NULL)
                  return vecRet;
             jint len = env->GetArrayLength(ar);
             jstring is;
             string ret;
             for(int i=0; i< len; i++)
            {
                  is = (jstring)env->GetObjectArrayElement(ar,i);

           //자바 함수를 통해 얻은 jstring을 c형태의 스트링으로 변환하여 저장. http://okjsp.pe.kr/seq/43731 참조
                  ret = jbyteArray2cstr(env,javaGetBytes(env,is));
                  //printf("%s\n",ret.c_str());
                  vecRet.push_back(ret);
             }

         }
        else
        {
              printf("mid error\n");
              return vecRet;
         }

     }

}
else
{
    printf("Can't find class\n");
    return vecRet;
}

 

 

[출처] http://saintrv.egloos.com/2373988

 

Comments