SymbolLookup — 외부 라이브러리에서 심볼의 주소를 찾는 인터페이스

SymbolLookup — 외부 라이브러리에서 심볼의 주소를 찾는 인터페이스

SymbolLookup하나 이상의 라이브러리에서 심볼(symbol)의 주소를 찾아내는 기능을 제공하는 인터페이스예요. 심볼은 함수나 전역 변수처럼 이름이 붙은 엔티티를 뜻해요.

출처: Java API Reference

본문

이 인터페이스는 java.lang.foreign 패키지의 일부로, preview API예요. 즉 preview 기능을 활성화해야 쓸 수 있고, 향후 릴리스에서 제거되거나 영구 기능으로 승격될 수 있어요.

심볼 룩업은 특정 라이브러리(또는 여러 라이브러리)를 기준으로 만들어진 뒤, find(String) 메서드가 심볼 이름을 받아 해당 라이브러리에서 그 심볼의 주소를 반환해요. 심볼의 주소는 길이가 0인 메모리 세그먼트(zero-length memory segment) 로 모델링되는데, 다양한 방식으로 사용돼요.

  • Linker에 전달해 downcall 메서드 핸들로 만들고, 그 세그먼트 주소의 외부 함수를 호출할 수 있어요.
  • 기존 downcall 메서드 핸들에, 밑에 있는 외부 함수의 인자로 전달할 수 있어요.
  • 다른 메모리 세그먼트 안에 저장할 수 있어요.
  • 전역 변수를 뒷받침하는 메모리 영역에 접근하는 데 쓸 수 있어요 (먼저 세그먼트를 리사이징해야 해요).

심볼 룩업 얻기

팩토리 메서드 SymbolLookup.libraryLookup(String, Arena)SymbolLookup.libraryLookup(Path, Arena)는 운영체제가 아는 라이브러리를 위한 심볼 룩업을 만들어요. 라이브러리는 이름이나 경로로 지정되고, 아직 로드되지 않았다면 로드돼요. 이 라이브러리 룩업의 수명은 Arena가 제어해요. 예를 들어 confined arena를 쓰면, 그 arena가 닫힐 때 연결된 라이브러리가 언로드돼요.

try (Arena arena = Arena.ofConfined()) {
    SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so", arena); // 여기서 libGL.so 로드
    MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
    ...
} // 여기서 libGL.so 언로드

JNI를 통해 이전에 로드된 라이브러리(즉 System.load(String)·System.loadLibrary(String)로 로드된 라이브러리)는 특정 클래스 로더와 연결돼 있어요. 팩토리 메서드 loaderLookup()은 호출자의 클래스 로더와 연결된 모든 라이브러리를 위한 심볼 룩업을 만들어요.

이 인터페이스는 함수형 인터페이스라서 람다 표현식이나 메서드 참조의 할당 대상으로 쓸 수 있어요.

더 알아보기 (Learn more)