Java는 기본적으로 플랫폼 독립적인 언어이지만, 때로는 성능이 중요한 작업이나 기존에 작성된 C/C++ 라이브러리를 활용해야 할 상황이 발생합니다. 이럴 때 JNI(Java Native Interface)를 사용하면 Java 코드에서 C++로 작성된 함수를 호출할 수 있습니다.
JNI란 무엇인가?
JNI(Java Native Interface)는 Java 가상 머신(JVM)과 네이티브 애플리케이션(C, C++, 어셈블리 등) 간의 상호작용을 가능하게 해주는 표준 프로그래밍 인터페이스입니다. JNI를 활용하면 하드웨어 제어, 고성능 연산, 운영체제 종속적인 기능 구현 등이 가능해집니다.
C++ 함수를 호출하는 단계별 방법
Java에서 네이티브 메서드(native method)를 사용하여 C++ 함수를 호출하는 절차는 다음과 같습니다.
1단계: 헤더 파일(.h) 생성
C++ 프로그램을 위한 헤더 파일을 생성합니다. 일반적으로 javac -h 명령어를 사용하여 Java 클래스로부터 자동으로 헤더 파일을 생성할 수 있습니다. 이 헤더 파일에는 Java에서 선언한 native 메서드에 대응하는 함수 시그니처가 포함됩니다.
2단계: CPP 파일 작성
생성된 헤더 파일을 include하여 실제 구현 내용을 담은 C++ 소스 파일(.cpp)을 작성합니다. 이 파일에 Java에서 호출하고자 하는 함수의 실제 로직을 구현합니다.
3단계: DLL(동적 링크 라이브러리) 생성
작성된 C++ 코드를 컴파일하여 DLL(Windows) 또는 공유 라이브러리(.so, Linux / .dylib, macOS) 형태로 빌드합니다. 이 라이브러리가 JVM에 의해 런타임에 로드됩니다.
4단계: Java 코드에서 네이티브 메서드 선언 및 호출
Java 코드에서 다음 작업을 수행합니다:
- 호출할 메서드를
native키워드로 선언합니다. System.loadLibrary()메서드를 사용하여 생성된 DLL을 로드합니다. 이때 확장자(.dll)는 생략하고 라이브러리 이름만 지정합니다.- 선언된 네이티브 메서드를 일반 Java 메서드처럼 호출합니다.
간단한 예제 코드
public class NativeDemo {
// 네이티브 메서드 선언
public native void displayMessage();
static {
// DLL 로드 (확장자 제외)
System.loadLibrary("nativeLib");
}
public static void main(String[] args) {
new NativeDemo().displayMessage();
}
}주의사항
- DLL 파일은
java.library.path에 지정된 경로에 있어야 정상적으로 로드됩니다. - 메서드 이름은 헤더 파일에 생성된 JNI 규약(
Java_패키지명_클래스명_메서드명)을 반드시 따라야 합니다. - 플랫폼마다 별도의 네이티브 라이브러리를 빌드해야 하므로, 크로스 플랫폼 배포 시 유의해야 합니다.
이러한 과정을 통해 Java의 안정성과 C++의 고성능을 동시에 활용하는 애플리케이션을 개발할 수 있습니다.