Hello JNI (2), C로부터 문자열 전달 받기

From Evernote:

Hello JNI, C로부터 문자열 전달 받기

이전 글에서 작성한 Hello Jni 프로젝트를 조금 수정해서 C로부터 문자열을 전달 받아온 후에 자바에서 화면에 출력해 볼 것이다.


먼저, 자바 프로젝트는 다음과 같이 수정한다.

package kr.pe.elex.example.jni;

/**
 * JNI 테스트
 *
 * @version 2
 * @author Elex
 */
public class HelloJni {

       static {
            System. loadLibrary("libhellojni");
      }

       /**
       * C 언어에서 한 줄 출력한다.
       */
       private native void printOut();

       /**
       * C 언어에서 문자열을 전달 받는다.
       *
       * @return
       */
       private native String getStringFromC();

       public static void main(String[] args) {

            HelloJni test = new HelloJni();
             // test.printOut();
            System. out.println(test.getStringFromC());
      }

}

#. 리턴 값이 있는 네이티브 메서드가 하나 추가되었다.

#. 메인 메서드에서는 네이티브 메서드로부터 가져온 문자열을 화면에 출력해 주도록 변경되었다.



헤더 파일을 추출해 보면 다음과 같은 함수 원형이 추가되었음을 확인할 수 있다.

/*
 * Class:     kr_pe_elex_example_jni_HelloJni
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL _Java_kr_pe_elex_example_jni_HelloJni_getStringFromC
  (JNIEnv *, jobject);

#. 함수 이름 앞에 밑줄(_) 추가해주는 것을 잊으면 안된다.

#. 리턴 값으로 jstring 타입이 지정되어 있다. jstring은 자바의 문자열 표현 방식이지, C언어의 문자열 표현 방식은 아니다.




헤더 파일에 선언된 함수 원형에 따라 C 소스 파일을 다음과 같이 수정한다.

/*
 * hellojni.c
 * JNI 테스트를 위한 C 라이브러리
 *      Author: Elex
 */

#include "kr_pe_elex_example_jni_HelloJni.h"

JNIEXPORT void JNICALL
_Java_kr_pe_elex_example_jni_HelloJni_printOut (JNIEnv *env, jobject obj)
{
  puts( "Hello Jni !");
}

JNIEXPORT jstring JNICALL
_Java_kr_pe_elex_example_jni_HelloJni_getStringFromC (JNIEnv *env, jobject obj)
{
  return (*env)-> NewStringUTF(env, "Hello Jni from C!");
}

#. 문자열을 반환하는 메서드가 하나 추가되었다.

#. 첫 번째 매개변수인 JNIEnv 인터페이스 포인터는 함수 테이블의 위치를 가리키고 있는 포인터이다. 이 함수 테이블의 각 항목은 JNI 함수를 가리키고 있다. 네이티브 함수는 항상 JNI 함수들을 통해서 JVM의 데이터 구조에 접근하게 된다.
즉, 이클립스에서 (*env)-> 를 타이핑하면 함수 목록이 뜨는데 자바와 C가 서로 주고 받는 데이터를 변환해주는 함수들이다.

#. JNI 함수 중 NewStringUTF()를 사용해서 새로운 유니코드 문자열을 생성하고 반환한다. NewStringUTF()는 새로운 자바 문자열을 생성하는 함수다.

#. 참고로, 두번째 매개변수인 jobject는 현재 메서드를 호출한 자바 인스턴스이다. 하지만 만일, 호출한 자바 메서드가 정적(static) 메서드라면 jobject는 현재 메서드를 정의한 클래스이다.




C 프로젝트를 빌드한 후, 자바 프로젝트를 실행하면...

C 라이브러리로부터 전달 받은 "Hello Jni from C!"라는 문자열이 콘솔 화면에 출력되는 것을 확인할 수 있다.


<프로젝트 파일>
http://www.elex.pe.kr/attachment/cfile9.uf@226E5243522CDA072758C3.7z


<예고>
다음에는 자바에서 C로 문자열을 전달해 볼 것이다.

댓글

이 블로그의 인기 게시물

자바 암호화 확장 (JCE) 관련 자바 1.8.0_151 이후 변경 사항

좌표 변환: 회전 이동

Apache Commons CSV