본문 바로가기

개발/Java & Spring

[Java] JNI로 c 소스파일 불러오기

어쩌다보니 dll 파일을 불러와서 웹서버를 개발해야하는 일이 생겨서 미리 jni 실습 ..! 



JNI(Java Native Interface)

JVM 안의 Java code를 C, C++, assembly와 같은 다른 언어로 짜여진 어플리케이션이나 라이브러리와 상호작용할 수 있도록 하는 인터페이스



사용하는 경우

  • 일반 자바 클래스 라이브러리가 플랫폼 의존적인 기능을 지원하지 못할 때

  • 다른 언어로 짜여진 라이브러리를 자바에서 사용하고 싶은 경우

  • 성능 이슈가 있을 수 있는 코드를 assembly 언어와 같은 low-level로 짜서 속도 향상을 도모하고 싶을 때


실습예제



JNITest.java

public class JNITest {

static {
System.loadLibrary("JNILib");//JNILib.dll(Window default format)호출
}

public native void hello();//native modifier -> JNILib에서 호출

public static void main(String[] args) {
JNITest jni=new JNITest();
jni.hello();
}

}

실행하면 오류가 나는데(Exception in thread "main" java.lang.UnsatisfiedLinkError: no JNILib in java.library.path) 오류는 무시하고 워크스페이스/프로젝트폴더/bin 디렉터리로 이동한다.

JNITest.class 파일만 있는데 shift + 마우스오른쪽 클릭 후 "여기서 명령창 열기"를 누른 후

javah 패키지명.클래스명 (패키지가 없으면 클래스명만)을 입력한다.

(javah 내부 또는 외부명령 어쩌고 에러가 발생하면 java 환경변수 셋팅을 다시 확인해준다)

정상적으로 실행되면 JNITest.h 파일이 새로 생긴다.



불러올 JNILib.dll 생성하기(Visual Studio 2017 기준)


  1. 새프로젝트 -> 빈프로젝트(dll파일 이름이 되므로 신경써준다.)

  2. 헤더 파일 오른쪽클릭 -> 추가 -> 기존항목 -> java 에서 생성했던 h 파일 불러오기

    헤더파일 내 include, JNIEXPORT 부분에 컴파일 에러가 뜨는데 jni.h 가 포함이 안되어있어서 그렇다.

  3. 소스파일 오른쪽클릭 -> 추가 -> c 또는 cpp 소스파일 추가

  4. 솔루션 오른쪽 클릭 -> 속성

4-1. 구성형식 - 동적라이브러리(.dll)로 수정 


4-2. C/C++(이게 없으면 .c or .cpp 소스파일 생성이 안된 것) 

jni.h를 불러오기 위해 디렉토리를 아래 사진과 같이 설정하고, 추가로 h가 들어있는 java프로젝트 bin 폴더도 추가한다(아래사진에는 없음)



5. c 파일 수정 

JNIEXPORT void JNICALL Java_JNITest_hello
(JNIEnv *, jobject);
JNITest.h 의 이부분을 c 파일에서 구현해준다.


JNILib.c
#include <stdio.h>
#include <jni.h>
#include "JNITest.h"

JNIEXPORT void JNICALL Java_JNITest_hello
(JNIEnv * env, jobject jobj) {
printf("Hello JNI");
}
- 변수 명 부분 수정한 것 확인!! 



6. 솔루션 빌드 

출력창에 dll 파일 경로가 같이 출력된다. 해당 디렉토리로 이동해서 dll 파일을 복사한 뒤 java프로젝트 폴더 안에 붙여넣기한 후 실행하면,


정상적으로 출력된다.


제대로 안된다면 비주얼스튜디오에서 



이부분이 이렇게 맞추어져있는지 확인한다. 안맞춰져있다면 이렇게 수정한 뒤 다시 처음부터 해야한다!! 


-끝-