Java

JNI - Java Native Interface

팡세영 2024. 2. 8. 09:26

Java Native Interface란?

자바에서 C, C++로 작성된 모듈을 호출할 수 있게 해주는 기능입니다.

자바는 JVM 위에서 실행되기 때문에 특정 운영체제에 종속되지 않고 사용할 수 있다는 장점이 있습니다.

하지만 반대로 JVM이 운영체제의 모든 기능을 JVM이 담지 못한다는 단점이 있습니다.
이러한 단점으로 인해 특정 기능들은 Java 언어로 구현을 하지 못하는 경우가 있습니다.

예를 들어) 성능 최적화, System call, 특정 하드웨어 장치 제어 

 

이렇게 Java 언어로 특정 기능을 구현하지 못하는 경우 C, C++로 고유 기능을 만들어 Java 메서드와 연결해주는 역할을 합니다.


그럼 함께 예제 코드를 봐볼까요?

1단계) Java 클래스 생성 및 네이티브 메서드 선언

public class HelloWorld {
    public native void printHelloWorld();

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

    public static void main(String[] args) {
        new HelloWorld().printHelloWorld();
    }
}

 

2단계) C에서 네이티브 메서드 구현

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"

JNIEXPORT void JNICALL Java_HelloWorld_printHelloWorld(JNIEnv *env, jobject obj) {
    printf("Hello World from C!\n");
}

 

3단계) 네이티브 라이브러리 컴파일 및 로드

C코드를 컴파일하여 공유 라이브러리 'libhelloworld.so' 또는 'helloworld.dll'를 생성해야 합니다.

 

Linux

gcc -shared -fpic -o libhelloworld.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux HelloWorld.c

 

Window

gcc -shared -o helloworld.dll -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" HelloWorld.c

 

4단계) Java 애플리케이션 실행

Java를 실행하여 네이티브 메서드를 호출할 수 있습니다.


코틀린에서도 JNI를 구현할 수 있지만 몇가지 주의해야 할 점이 있습니다.

  1. 네이티브 메서드 선언의 차이
    Java: native, Kotlin: external 
  2. Null 가능성
    kotlin에서는 Nullable을 명시적으로 다루기 때문에 주의해야 합니다.
  3. Kotlin의 특징
    kotlin에서 사용하는 inline function, 확장 함수 등 Kotlin의 고유기능들을 JNI와 함께 사용할 수 없습니다.