jni 개발

JNI(java native interface)
java에서 C 라이브러리를 참조할 때 사용하는 프레임워크.
즉, C 라이브러리를 java에서 사용하고 싶을 때 사용.

jni 개발 프로세스

  1. java : 참조할 C 라이브러리의 API 정의
  2. java : C header 생성
  3. C : 코드 작성 및 라이브러리 생성
  4. java : C 라이브러리 참조

1. java : 참조할 C 라이브러리의 API 정의

example/samples/sample.java

package example.samples;

public class jnisample {	
	private static native int add(int a, int b);

	public static void main(String[] args){
		// 생략
	}
}

2. java : C header 생성

  • 패키지가 있는 폴더(src)에서 "javah {java 파일}" 실행
    src/example/samples/sample.java

    • javah {package}.{class name}
      javah example.samples.jnisample
  • 아래와 같이 C header가 생성된다.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class example_samples_jnisample */

#ifndef _Included_example_samples_jnisample
#define _Included_example_samples_jnisample
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     example_samples_jnisample
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_example_samples_jnisample_add
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

3. C : 코드 작성 및 라이브러리 생성

visual studio 2017 사용

  • jni 헤더 참조

    • jni.h 경로 검색
      (everything util을 사용하면 편하다. )

    • jni 경로 등록
      C:\Program Files (x86)\Java\jdk1.5.0_22\include
      C:\Program Files (x86)\Java\jdk1.5.0_22\include\win32

      {jni.h 경로}와 {jni.h 경로\win32}를 "프로젝트 속성 --> C/C++ --> 일반 --> 추가 포함 디렉터리"에 입력한다.

  • C header에서 선언된 함수를 정의한다.

#include "example_samples_jnisample.h"
#include <jni.h>

#ifdef __cplusplus
extern "C" {
#endif
	/*
	 * Class:     example_samples_jnisample
	 * Method:    add
	 * Signature: (II)I
	 */
	JNIEXPORT jint JNICALL Java_example_samples_jnisample_add
	(JNIEnv *env, jclass jcl, jint a, jint b) {
		return a + b;
	}

#ifdef __cplusplus
}
#endif
  • 라이브러리를 생성한다.

    생성된 라이브러리 : c.dll

4. java : C 라이브러리 참조

  • java : C 라이브러리 참조 구현 (System.loadLibrary)
    생성된 라이브러리 : c.dll
    확장자 명을 제거하여 입력 : "c"
	static {
		System.loadLibrary("c");
	}
  • (참고) test 코드 구현
package example.samples;

public class jnisample {	
	private static native int add(int a, int b);

	public static void main(String[] args){
		int c = add(1, 5);
		System.out.println(c);
	}

	static {
		System.loadLibrary("c");
	}
}
  • 컴파일 및 실행
    javac example\samples\jnisample.java
    java example.samples.jnisample

    실행결과
    6


참고

  • err : Can't load IA 32-bit .dll on a AMD 64-bit platform
    생성한 C 라이브러리와 java 의 운영체제(x82 또는 x64)가 맞지 않는 경우다.
    java에 맞춰 visual studio의 운영체제를 바꿔주는게 편하다.
  • err : Exception in thread "main" java.lang.UnsatisfiedLinkError
    Jni dll 라이브러리 인식 실패.
    • 생성한 C 라이브러리와 java 의 운영체제(x82 또는 x64)가 맞지 않는 경우 주로 발생한다.
    • library를 잘못 생성한 경우,

      (경험) c header 복붙하다가 #ifdef를 안 지워서 이러한 에러 발생
      #ifndef _Included_example_samples_jnisample
      #define _Included_example_samples_jnisample
      빌드는 되서 찾기가 어렵다...

  • jni 정의
    자바 네이티브 인터페이스(Java Native Interface, JNI)는 자바 가상 머신(JVM)위에서 실행되고 있는 자바코드가 네이티브 응용 프로그램(하드웨어와 운영 체제 플랫폼에 종속된 프로그램들) 그리고 C, C++ 그리고 어샘블리 같은 다른 언어들로 작성된 라이브러리들을 호출하거나 반대로 호출되는 것을 가능하게 하는 프로그래밍 프레임워크이다.

  • eclipse로 C header를 생성하는 방법도 있는 것 같지만... 복잡하다.

좋은 웹페이지 즐겨찾기