System.loadLibrary(String)
, which takes the name of the library as a parameter. After this call, the library will be loaded into the JVM address space.package my.mega.pack ;Here we, for convenience, carried
public class NativeCallsClass
{
static
{
System . loadLibrary ( "megalib" ) ;
}
native public static void printOne ( ) ;
native public static void printTwo ( ) ;
}
loadLibrary()
in static area of a class.NativeCallsClass.printOne()
. Then the JVM will search the libraries for a method with the following name: Java_my_mega_pack_NativeCallsClass_printOne(...)
.javac -d bin / src / my / mega / pack / NativeCallsClass.java cd bin javah my.mega.pack.NativeCallsClass
/ * DO NOT EDIT THIS FILE - it is machine generated * /The most important thing here is the signatures of 2 functions:
#include <jni.h>
/ * Header for class my_mega_pack_NativeCallsClass * /
#ifndef _Included_my_mega_pack_NativeCallsClass
#define _Included_my_mega_pack_NativeCallsClass
#ifdef __cplusplus
extern "C" {
#endif
/ *
* Class: my_mega_pack_NativeCallsClass
* Method: printOne
* Signature: () V
* /
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printOne
( JNIEnv * , jclass ) ;
/ *
* Class: my_mega_pack_NativeCallsClass
* Method: printTwo
* Signature: () V
* /
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printTwo
( JNIEnv * , jclass ) ;
#ifdef __cplusplus
}
#endif
#endif
Java_my_mega_pack_NativeCallsClass_printOne(JNIEnv *env, jclass myclass)
and Java_my_mega_pack_NativeCallsClass_printTwo(JNIEnv *env, jclass myclass)
.NativeCallsClass
. Note that the jclass as the second parameter is passed when the method is declared as static. If it were an ordinary method, then a jobject would be passed to us, which would identify the object whose method we called (in fact, this is an analogue of this).#include <iostream>
#include "my_mega_pack_NativeCallsClass.h"
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printOne ( JNIEnv * env, jclass myclass )
{
std :: cout << "One" << std :: endl ;
}
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printTwo ( JNIEnv * env, jclass myclass )
{
std :: cout << "Two" << std :: endl ;
}
package my.mega.pack ;Run javah and see that the method signatures have changed a bit. Now they are:
public class NativeCallsClass
{
static
{
System . loadLibrary ( "megalib" ) ;
}
native public static int inputInt ( ) ;
native public static void outputInt ( int v ) ;
}
JNICALL Java_my_mega_pack_NativeCallsClass_inputInt ( JNIEnv * , jclass ) ;jint is typedef. In fact, it denotes some primitive type (for example, int), which corresponds to an int in java. As you can see, the task was not much more complicated than the previous one :) Our functions will look like this:
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_outputInt ( JNIEnv * , jclass, jint ) ;
#include <iostream>
#include "my_mega_pack_NativeCallsClass.h"
JNIEXPORT jint JNICALL Java_my_mega_pack_NativeCallsClass_inputInt ( JNIEnv * env, jclass myclass )
{
int ret;
std :: cin >> ret;
return ret;
}
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_outputInt ( JNIEnv * env, jclass myclass, jint v )
{
std :: cout << v << std :: endl ;
}
Source: https://habr.com/ru/post/49660/
All Articles