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:
- 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.
- 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.
- Ł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.