Java Geek
2.45K subscribers
272 photos
1 file
24 links
Практичные советы, лайфхаки и код для Java-разработчиков. Каждый пост — реальная польза. Учим Java на примерах.

По всем вопросам @evgenycarter
Download Telegram
🌉 Project Panama. Как вызвать C/C++ без боли?

Java долгое время жила в изоляции. Чтобы выйти за пределы JVM (вызвать функцию из OS, использовать библиотеку ML на C++ или графику на Rust), нам приходилось писать "клей" (glue code) на C.

Project Panama (Foreign Function & Memory API) меняет парадигму. Теперь Java умеет говорить с нативным кодом напрямую.

🗑 Что мы выбрасываем (JNI)

1. Больше не нужно писать ни строчки на C/C++.
2. Больше нет утилиты javah.
3. Больше нет риска, что Unsafe удалят и ваш код сломается.

Как это работает (FFM API)

Допустим, мы хотим вызвать стандартную функцию strlen из библиотеки C, чтобы узнать длину строки.

Шаг 1. Находим библиотеку


Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();

// Ищем адрес функции "strlen" в памяти процесса
MemorySegment strlenAddress = stdlib.find("strlen").orElseThrow();



Шаг 2. Описываем сигнатуру (Descriptor)
Мы говорим Java: "Эта функция принимает указатель (Адрес) и возвращает число (long)".


FunctionDescriptor descriptor = FunctionDescriptor.of(
ValueLayout.JAVA_LONG, // Возвращаемое значение
ValueLayout.ADDRESS // Аргумент (указатель на строку)
);

MethodHandle strlen = linker.downcallHandle(strlenAddress, descriptor);



Шаг 3. Выделяем память и вызываем
Самое интересное: мы аллоцируем память вне Java кучи (Off-heap) безопасным способом через Arena.


try (Arena arena = Arena.ofConfined()) {
// Превращаем Java String в C-строку (char*)
MemorySegment cString = arena.allocateFrom("Hello Panama!");

// Вызываем функцию C прямо из Java!
long length = (long) strlen.invoke(cString);

System.out.println(length); // 13
}
// Тут память автоматически очищается (как free() в C)



🤖 Killer Feature: jextract

Вы скажете: "Писать дескрипторы для каждой функции вручную? Это же муторно!"
И вы правы. Поэтому есть утилита jextract.

Вы просто "скармливаете" ей заголовочный файл .h:


jextract --output src -t org.example.opengl /usr/include/GL/gl.h



Она сама сгенерирует все Java-классы и методы. Вы просто пишете:


gl.glClear(gl.GL_COLOR_BUFFER_BIT());



Это выглядит и работает как обычный Java-код, но под капотом вызывает OpenGL напрямую.

🧠 Зачем это нужно?

1. AI и ML: TensorFlow, PyTorch, OpenCV - все они написаны на C++. Теперь Java может использовать их без тормозов JNI.
2. Базы данных: Драйверы могут работать напрямую с сетевым стеком OS (io_uring).
3. Rust: Вы можете написать критически важную логику на Rust, скомпилировать в библиотеку и использовать в Java.

🏆 Итог серии Modern Java

• Она запускается мгновенно (GraalVM).
• Она держит миллионы соединений (Virtual Threads).
• Она безопасна и лаконична (Records, Sealed Classes).
• Она открыта миру (Panama).

#ProjectPanama #FFM #Native #Performance

👉 @java_geek
👍41🤯1