FFI
1. 개요
FFI는 Foreign Function Interface
의 약자입니다. 이는 어떤 프로그래밍 언어세서 다른 프로그래밍 언어나 라이브러리의 함수를 호출하고 사용하기 위한 인터페이스를 의미합니다.
FFI는 일반적으로 서로 다른 언어 간에 상호 운용성(interoperability)을 제공하기 위해 사용됩니다. 프로그래밍 언어 간에는 다양한 규칙과 데이터 형식이 존재하기 때문에, 다른 언어나 라이브러리의 함수를 직접 호출하는 것은 어려울 수 있습니다. 이런 경우에 FFI를 사용하여 함수 호출 및 데이터 전달을 처리할 수 있습니다.
FFI는 일반적으로 프로그래밍 언어의 컴파일러나 인터프리터에서 제공하는 기능이며, 언어에 따라 구현 방식이 다를 수 있습니다. 예를 들어, C 언어에서는 FFI를 통해 다른 언어의 함수를 호출하거나 C 함수를 다른 언어에서 호출할 수 있습니다. Java에서는 JNI(Java Native Interface)라는 FFI를 제공하여 C나 C++로 작성된 함수를 호출할 수 있습니다.
FFI는 다른 언어나 플랫폼에 구애받지 않고 다양한 기능을 사용할 수 있도록 도와주는 중요한 도구입니다. 이를 통해 다른 언어나 라이브러리의 장점을 활용하면서도 프로그래밍 언어의 생산성과 효율성을 유지할 수 있습니다.
2. 자바에서의 FFI
자바에서 FFI를 구현하려면 JNI(Java Native Interface)혹은 JNA(Java Native Access) 를 사용하면 됩니다. 두가지 방법은 각각 장단점이 있으며 다음과 같은 차이점이 있습니다.
1. JNI (Java Native Interface)
JNI는 네이티브 코드와 직접적으로 상호 작용하기 때문에 매우 뛰어난 성능을 제공 합니다. 네이티브 코드에 접근하기 위해 자바와 C/C++ 사이의 직접적인 매핑을 사용합니다.
JNI를 사용하면 자바에서 네이티브 코드에 직접 메모리를 할당하고 조작할 수 있습니다. 이는 성능이 중요하거나 복잡한 데이터 구조를 다룰 때 유용합니다.
JNI는 복잡한 구현이 필요하며, 네이티브 코드와 자바 사이의 인터페이스를 명시적으로 작성해야 합니다. 이로 인해 개발 과정이 번거로울 수 있습니다.
JNI는 플랫폼에 종속적입니다. 네이티브 코드의 컴파일이 필요하며, 특정 플랫폼에 맞춰야 합니다.
JNI는 직접 C 코드를 작성해야 하기 때문에 따로 예제코드를 작성하지 않습니다.
2. JNA (Java Native Access)
JNA는 네이티브 코드와 자바 간의 인터페이스를 자동으로 처리해주는 라이브러리입니다. 별도의 네이티브 헤더 파일을 작성할 필요 없이, 자바 인터페이스를 선언하고 JNA가 자동으로 매핑을 처리합니다.
JNA는 플랫폼에 독립적입니다. 네이티브 라이브러리를 로드하고 사용할 수 있는 기능을 제공하며, 플랫폼에 종속되지 않습니다.
JNI에 비해 JNA는 약간의 성능 손실이 있을 수 있습니다. JNA는 동적 라이브러리 매핑과 추가적인 오버헤드를 포함하기 때문입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
public class HelloController {
public interface User32 extends Library {
User32 INSTANCE = (User32) Native.load("user32", User32.class);
int MessageBoxA(int hWnd, String lpText, String lpCaption, int uType);
}
@FXML
protected void onHelloButtonClick() {
User32.INSTANCE.MessageBoxA(0, "Hello from Java!", "MessageBox Example", 0);
}
}
간단한 예제입니다. 몇줄되지 않는 코드로 버튼 클릭시 Win32 API - MessageBoxA 함수를 호출하는 것을 확인할 수 있습니다.
그래서?
JNI와 JNA는 각각의 상황과 용도에 따라 선택해야 합니다. 성능과 직접 메모리 접근이 중요한 경우에는 JNI가 적합하며, 플랫폼 독립성과 개발 편의성이 중요한 경우에는 JNA를 고려할 수 있습니다.