상세 컨텐츠

본문 제목

인텔리제이에서 JNI 테스트

개발

by 차차승 2024. 12. 10. 10:52

본문

JNI란

Java Native Interface의 약자로 자바 코드에서 네이티브 코드를 호출하거나 반대로 네이티브 코드에서 Java 코드를 호출할 수 있게 해주는 프레임워크이다.

 

C++ 라이브러리를 만들어 인텔리제이에서 Java 코드에서 컴파일 될 수 있는 것을 간단하게 만들어 보았다.

 

1. 먼저 src 폴더 아래 native_code.c 를 생성

 

native_code.c

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

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

 

 MyClass.java

public class MyClass {
    static {
//        System.loadLibrary("native_code");
//        System.load("${/Users/sycha11/IdeaProjects/JNITest/libnative_code.dylib}");

        String path = System.getProperty("user.dir") + "/libnative_code.dylib";
        System.load(path);
    }

    private native void sayHello();

    public static void main(String[] args) {
        new MyClass().sayHello();
    }
}

 

 

2. 헤더 파일 생성

  • 터미널을 열고 프로젝트의 src 디렉토리로 이동
  • javac -h . MyClass.java 명령을 실행하여 헤더 파일을 생성합니다.
  • 이 명령은 MyClass.h 헤더 파일을 생성합니다.

 

3. 네이티브 라이브러리 컴파일

  • C 코드 컴파일
gcc -shared -o libnative_code.dylib -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin native_code.c

 

이 과정에서 jni.h가 없다는 오류가 발생하였다.

 

문제 원인 : JAVA_HOME 경로 설정이 되어 있지 않아 생기는 문제였다.

해결 방법 :

echo JAVA_HOME

 

먼저 JAVA_HOME 경로를 확인하고 경로를 추가 해야 한다.

 

현재 MAC OS를 사용하고 있고 # Zsh 사용자 

 

1. 셀 설정 파일 열기

nano ~/.zshrc

 

2. 환경변수 추가

export JAVA_HOME=$(/usr/libexec/java_home)

 

3. 변경사항 저장

Ctrl+X를 누른 후, Y를 입력하고 Enter를 눌러 저장합니다.

 

4. 변경사항 적용

source ~/.zshrc   # Zsh 사용자

 

5. 설정 확인

echo $JAVA_HOME

 

추가 되었을 것이다.

 

  • C 코드 컴파일
    • 다음 명령을 실행하여 C 코드를 컴파일 한다.
    •  
gcc -shared -o libnative_code.dylib -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin native_code.c

 

여기서 .dylib와 .so 는 mac os는 .dylib를 사용 linux는 .so를 사용 한다.

 

4. 라이브러리 로드 및 실행

  • 라이브러리 위치 설정
    1. System.loadLibaray
      • 절대 경로를 필요로 하므로 플랫폼 간 이식성이 떨어집니다.
      • 의존성 있는 라이브러리가 같은 디렉토리에 있어도 로드하지 못할 수 있습니다
    2. System.load
      • 절대 경로가 필요하다.
      • Java 17 이상에서는 무조건 절대 경로만 인식한다고 한다.
String path = System.getProperty("user.dir") + "/libnative_code.dylib";
System.load(path);

 

 

 

'개발' 카테고리의 다른 글

[C++] RAII 패턴  (0) 2024.12.20
[Java] ClassPath로 .jar 파일 사용하기  (0) 2024.12.12
안드로이드 스튜디오 gradle syn 에러  (2) 2024.12.11

관련글 더보기