Нативна бібліотека

Це бібліотека, написана на мові програмування, яка компілюється безпосередньо в машинний код, специфічний для певної архітектури або операційної системи. Нативні бібліотеки використовуються програмами, що написані на тій же мові програмування або через механізми міжмовної взаємодії, такі як JNA/JNI в Java. Нативні бібліотеки можуть бути як статичними, так і динамічними.

Статична бібліотека

Набір функцій, які включаються безпосередньо в бінарний файл програми на етапі компіляції. Вони стають нероздільною частиною програми.

Динамічна бібліотека

Не включається в бінарний файл програми на етапі компіляції. Замість цього, програми завантажують динамічні бібліотеки в пам'ять під час виконання, коли це необхідно. Декілька програм можуть використовувати одну й ту ж динамічну бібліотеку, що допомагає економити пам'ять.

Динамічні бібліотеки зазвичай мають розширення .dll на Windows, .so на Linux і .dylib на macOS.

І логічно, що завантаження бібліотеки вимагає щоб вона була присутньою на системі під час виконання.

JNA

або Java Native Access — це один з інструментів Java, який дозволяє розробникам забезпечити безпосередній доступ до native-функцій та бібліотек, написаних на C, C++ та інших мовах. Це корисно, коли вам потрібно використовувати функції, які не доступні в стандартній бібліотеці Java, або коли вам потрібно покращити продуктивність за допомогою нативного коду.

Основна концепція полягає в тому, щоб створити Java інтерфейс, що відповідає нативній бібліотеці, і використовувати цей інтерфейс для виклику native-функцій. JNA контролює всі нюанси прив'язки, включаючи перетворення типів даних і виклик функцій.

Що це нам дає?

1. Доступ до native API: Часто Java може не мати доступу до специфічних функцій операційної системи або апаратного забезпечення. JNA дозволяє викликати ці функції напряму.

2. Продуктивність: Деякі операції можуть бути виконані швидше в native-коді, ніж в Java. JNA дозволяє вам використовувати ці оптимізації.

Створення JNA-інтерфейсу

Спершу ви маєте визначити Java інтерфейс, що відображає native-бібліотеку. Цей інтерфейс має включати сигнатури всіх функцій, які ви хочете викликати. Потім ви викликаєте ці функції через JNA, який конвертує Java типи даних у відповідні нативні типи.

Припустимо, ми хочемо викликати getpid (отримати ID потоку) і getenv, який повертає значення змінної оточення. Спочатку, нам потрібно додати залежність JNA до нашого проекту.

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.13.0</version>
</dependency>

Тепер створимо JNA інтерфейс для бібліотеки libc *, яка містить getpid і getenv:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

public interface CLibrary extends Library {
    CLibrary INSTANCE = Native.load((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);

    int getpid();
    String getenv(String name);
}

Main:

public class Main {
    public static void main(String[] args) {
        CLibrary cLibrary = CLibrary.INSTANCE;
        int getpid = cLibrary.getpid();
        System.out.println("Process ID: " + getpid);
        System.out.println("------");
        String path = cLibrary.getenv("PATH");
        System.out.println(path);
    }
}

Result:

Process ID: 10228
------
/opt/homebrew/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin

Process finished with exit code 0

Ми бачимо, що виклик нативної функції відбувається так само, як і виклик звичайного методу.

— дуже абстрактна схема —

Важливо пам'ятати, що використання нативних бібліотек з Java може зробити ваш код менш переносимим і більш схильним до помилок, оскільки він стає залежним від деталей конкретної операційної системи та архітектури процесора. Тому, цей механізм потрібно використовувати обережно.

Які програми використовують JNA?

Intellij IDEA, Elasticsearch, Apache NetBeans IDE, Apache Cassandra, OSHI та інші.

IntelliJ IDEA Community


libc є стандартною бібліотекою C в багатьох системах, основаних на Unix, включаючи Linux та macOS. Вона містить багато стандартних функцій мови C, таких як введення/виведення, робота з рядками, математичні функції тощо.

https://github.com/java-native-access/jna

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Oleksandr Klymenko
Oleksandr Klymenko@overpathz

Java Software Engineer

4.7KПрочитань
1Автори
71Читачі
На Друкарні з 19 квітня

Більше від автора

  • Secure networking. Deep Dive

    Глибоке занурення в протоколи TLS/SSL та інфраструктуру відкритих ключів (PKI). Основні поняття, процес встановлення захищеного з'єднання, роль сертифікатів та ланцюжка довіри

    Теми цього довгочиту:

    Security
  • Поширені помилки у дизайні REST API

    У довгочиті розглядаються поширені помилки при проектуванні REST API та способи їх уникнення: версіонування, використання DTO, підхід CQRS, робота з мікросервісами, та інші практики для підвищення продуктивності, безпеки й зручності API

    Теми цього довгочиту:

    Java
  • Java. Короткий огляд еволюції багатопотоковості

    У перших версіях Java багатопоточність реалізовувалася за допомогою класу Thread, який дозволяв створювати нові потоки. Проте ця модель мала багато недоліків:

    Теми цього довгочиту:

    Java

Вам також сподобається

Коментарі (1)

Привіт. Гарна тема, останнім часом цікавився нею. Чи можеш ти відписати мені в лінкедині? Хочу декілька запитань спитати стосовно використання JNA/JNI: Vadym Kain | LinkedIn

Вам також сподобається