JNIのRegisterNatives()メソッドを使用するにはどうすればよいですか?
1. 概要
この短いチュートリアルでは、 JNI RegisterNatives()メソッドを見ていきます。このメソッドは、Java関数とC++関数の間のマッピングを作成するために使用されます。
まず、JNIがどのように機能するかを説明します RegisterNatives() 作品
2. JNI RegisterNativesメソッド
JVMには、ネイティブメソッドを見つけてJavaコードにリンクする2つの方法があります。 1つ目は、特定の方法でネイティブ関数を呼び出し、JVMがそれを見つけられるようにすることです。 もう1つの方法は、 JNI RegisterNatives()メソッドを使用することです。
名前が示すように、 RegisterNatives()は、引数として渡されたクラスにネイティブメソッドを登録します。 このアプローチを使用することで、C++関数に任意の名前を付けることができます。
実際、 java .lang.Object’ s registerNatives()メソッドは2番目のアプローチを使用します。 CのOpenJDK8からのjava.lang.Object’ s registerNatives()メソッドの実装を見てみましょう。
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
まず、 method [] 配列が初期化され、JavaとC++の関数名間のマッピングが格納されます。 次に、非常に特殊な方法で名前が付けられたメソッドJava_java_lang_Object_registerNativesが表示されます。
そうすることで、JVMはそれをネイティブの java .lang.Object’ s registerNatives()メソッドにリンクできます。 その中で、 method []配列がRegisterNatives()メソッド呼び出しで使用されます。
それでは、独自のコードでどのように使用できるかを見てみましょう。
3. RegisterNativesメソッドの使用
Javaクラスから始めましょう:
public class RegisterNativesHelloWorldJNI {
public native void register();
public native String sayHello();
public static void main(String[] args) {
RegisterNativesHelloWorldJNI helloWorldJNI = new RegisterNativesHelloWorldJNI();
helloWorldJNI.register();
helloWorldJNI.sayHello();
}
}
2つのネイティブメソッドを定義します。 登録() と
Javaのregister()ネイティブメソッドのC++実装を見てみましょう。
static JNINativeMethod methods[] = {
{"sayHello", "()Ljava/lang/String;", (void*) &hello },
};
JNIEXPORT void JNICALL Java_com_baeldung_jni_RegisterNativesHelloWorldJNI_register (JNIEnv* env, jobject thsObject) {
jclass clazz = env->FindClass("com/baeldung/jni/RegisterNativesHelloWorldJNI");
(env)->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0]));
}
java.lang.Object の例と同様に、最初にJavaメソッドとC++メソッド間のマッピングを保持する配列を作成します。
それで、
この関数は2つのことを行います。 まず、目的のJavaクラスを見つけます。 次に、 RegisterNatives()メソッドを呼び出し、クラスとマッピング配列を渡します。
これで、2番目のネイティブメソッド sayHello()を好きなように呼び出すことができます。
JNIEXPORT jstring JNICALL hello (JNIEnv* env, jobject thisObject) {
std::string hello = "Hello from registered native C++ !!";
std::cout << hello << std::endl;
return env->NewStringUTF(hello.c_str());
}
完全修飾名の代わりに、短くて意味のある名前を使用しました。
最後に、 RegisterNativesHelloWorldJNIクラスからmain()メソッドを実行してみましょう。
Hello from registered native C++ !!
4. 結論
この記事では、JNI RegisterNatives()メソッドについて説明しました。。 最初に、 java.lang.Object.registerNatives()メソッドが内部で何をするかを説明しました。 次に、JNI RegisterNatives()メソッドの使用が役立つ理由について説明しました。 最後に、独自のJavaおよびC++コードでそれを使用する方法を示しました。
いつものように、記事の完全なソースコードは、GitHubでから入手できます。