Java, Spring
JNI, Java의 Native Code 사용 설명 및 예제
ted k
2023. 3. 5. 17:38
JNI
- C/C++ 등의 네이티브 언어로 작성된 코드와 상호작용할 수 있도록 하는 프로그래밍 인터페이스
- JNI를 통해 네이티브 언어와 함수 호출 및 데이터 전달이 가능하게 한다.
- 메시지 및 자바 객체
- 하드웨어 제어를 쉽게할 수 있게 한다.
- DLL 을 사용한다.
- DLL은 라이브러리에 대한 linking 만 해 두었다가
- 특정 메모리영역을 할당 받아서 필요한 내용만 loading 한다.
- 또한 특정 메모리 영역은 프로세스 간에 공유가 가능하다.
- 바이트 코드와 네이티브 코드를 동일한 바이너리 파일에 혼합할 수 없기 때문에 독립적으로 컴파일 / 실행 (JVM / GCC(or else)) 하고 메시지를 주고 받는다.
- 사용할 함수를 native 키워드를 통해 선언하고
- 가져올 DLL 을 static block 에 선언한다.
https://liltdevs.tistory.com/91
주메모리의 관리 Main Memory
주메모리의 관리, Main Memory memory에 Load된 program -> process 메모리는 바이트로 이뤄진 주소를 배열로 한다. PC(Programcounter) -> 주소 -> 명령어, 필요하면 더 데이터를 더 가져오거나 내보낼 수도 있다.
liltdevs.tistory.com
구현 예제
public class Sample {
static {
System.loadLibrary("sample");
}
private native void print(String message);
public static void main(String[] args) {
Sample sample = new Sample();
sample.print("Hello, JNI!");
}
}
- java로 전달한 메세지를 print 하는 간단한 소스를 만들어 준다.
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Sample */
#ifndef _Included_Sample
#define _Included_Sample
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Sample
* Method: print
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Sample_print(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
- 위와 같이 header file 이 생성되고
#include "sample.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_Sample_print(JNIEnv *env, jobject obj, jstring message) {
const char *msg = (*env)->GetStringUTFChars(env, message, NULL);
printf("%s\\n", msg);
(*env)->ReleaseStringUTFChars(env, message, msg);
}
- 맞춰서 실행하는 함수를 작성한다.
$ gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin/" -o libSample.jnilib -shared sample.c
- 위와 같이 컴파일 하면 libSample.jnilib 파일이 생성된다.
- 이제 클래스를 실행하면 원하는 문자열이 출력된다.