Przegląd JNI

Z punktu widzenia maszyny JVM istnieją dwa typy kodu: "Java™" i "native". Interfejs Java Native Interface (JNI) ustanawia dobrze zdefiniowany i niezależny od platformy interfejs między tymi dwoma.

Kod rodzimy może być używany razem z językiem Java na dwa różne sposoby: jako "metody rodzime" w uruchomionej maszynie JVM oraz jako kod tworający maszynę JVM przy użyciu interfejsu API wywołania. W tej sekcji opisano różnicę.

Metody rodzime

Rodzime metody języka Java są deklarowane w języku Java, implementowane w innym języku (takim jak C lub C + +) i ładowane przez maszynę JVM w razie potrzeby. Aby korzystać z metod rodzimych, należy:

  1. Deklaruj metodę rodzimą w kodzie Java.

    Gdy kompilator javac napotka rodzimą deklarację metody w kodzie źródłowym Java, rejestruje ona nazwę i parametry metody. Ponieważ kod źródłowy Java nie zawiera implementacji, kompilator oznacza metodę jako "native" (rodzime). Wirtualna maszyna języka Java może następnie poprawnie rozstrzygnąć metodę, gdy jest wywoływana.

  2. Zaimplementuj metodę rodzimą.

    Metody rodzime są implementowane jako zewnętrzne punkty wejścia w ładowalnej bibliotece binarnej. Zawartość biblioteki rodzimej jest specyficzna dla platformy. Interfejs JNI umożliwia maszynie JVM korzystanie z dowolnych rodzimych metod w sposób niezależny od platformy.

    Maszyna JVM wykonuje wywołania metod rodzimych. Gdy maszyna JVM znajduje się w metodzie rodzimej, JNI udostępnia metodę "call back" (wywołanie z powrotem) do maszyny JVM.

  3. Ładuj kod metody rodzimej dla maszyny wirtualnej, która ma być używana.

    Podobnie jak deklarowanie metody rodzimej, należy znaleźć i załadować bibliotekę rodzimą, która zawiera metodę w czasie wykonywania.

    Dwa interfejsy Java ładują rodzime biblioteki:

    • java.lang.System.load()
    • java.lang.System.loadLibrary()

    Zwykle klasa deklarujący metody rodzime ładuje bibliotekę rodzimą w inicjatorze statycznym.

Interfejs API wywołania

Tworzenie maszyny JVM wiąże się z kodem rodzimym. Aspekt JNI używany do tego celu jest nazywany interfejsem API JNI Invocation. Aby użyć funkcji API wywołania, należy powiązać ją z biblioteką współużytkowaną specyficzną dla implementacji, statycznie lub dynamicznie, a następnie wywołać funkcję JNI_ *, którą eksportuje.

Specyfikacja i implementacja JNI

Specyfikacja JNI jest nieprecyzyjna w przypadku wybranych szczegółów implementacji. Udostępnia on środowisko wielokrotnego użytku dla prostych i rozszerzalnych interfejsów rodzimych języka C i C + +. Model JNI jest również podstawą dla specyfikacji JVMTI.

Specyfikacja znaków towarowych Oracle Corporation i pakiet Java Compatibility Kit (JCK) zapewniają zgodność ze specyfikacją, ale nie z implementacją. Kod rodzimy musi być zgodny ze specyfikacją, a nie z implementacją. Kod napisany dla nieokreślonego zachowania jest podatny na przenośność i problemy z kompatybilnością w przód.