What Does the Registernatives() Method Do

What does the registerNatives() method do?

The other answers are technically correct, but not very useful for someone with no JNI experience. :-)

Normally, in order for the JVM to find your native functions, they have to be named a certain way. e.g., for java.lang.Object.registerNatives, the corresponding C function is named Java_java_lang_Object_registerNatives. By using registerNatives (or rather, the JNI function RegisterNatives), you can name your C functions whatever you want.

Here's the associated C code (from OpenJDK 6):

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]));
}

(Notice that Object.getClass is not in the list; it will still be called by the "standard" name of Java_java_lang_Object_getClass.) For the functions listed, the associated C functions are as listed in that table, which is handier than writing a bunch of forwarding functions.

Registering native functions is also useful if you are embedding Java in your C program and want to link to functions within the application itself (as opposed to within a shared library), or the functions being used aren't otherwise "exported", since these would not normally be found by the standard method lookup mechanism. Registering native functions can also be used to "rebind" a native method to another C function (useful if your program supports dynamically loading and unloading modules, for example).

I encourage everybody to read the JNI book, which talks about this and much more. :-)

Android JNI RegisterNatives: Call once with everything, or once per function

No problem calling RegisterNatives again and again.

JNI - Can I use RegisterNatives without calling System.loadLibrary for native plugins?

At least Android VM requires that all native methods must be "registered" when the class is instantiated. That's why System.load() is usually called in static constructor, and not later.

The two ways to resolve native methods are through RegisterNatives() in JNI_OnLoad() or though name matching (C exported functions names as reported by javah).

You can look for function pointers for RegisterNatives() in all loaded modules, or load more modules and get pointers from them. RegisterNatives() may be called at any time, and if you really want to unload some plugins you can make use of UnregisterNatives().

The latter was introduced to support the following flow (pseudo-code follows):

SwitchPlugin() {
UnregisterNatives();
unloadPlugin(oldHandle);
newHandle = loadPlugin(newPluginName);
RegisterNatives();
}

Your app will probably crash miserably if it tries to use a native method that is implemented in an unloaded plugin or after it is unregistered with UnregisterNatives().

How to use JNI registerNatives inside c++ class?

One option is that you give your Java code a means of getting a pointer to your native androidGPS object and passing it down to the non-class-function LocationChanged(), and it calls androidGPS::LocationChanged().

Callbacks into non-static C++ objects are problematic and typically are solved using a static helper function coupled with either a pointer to the object that the callback should be invoked on, or use of a static pointer to a singleton object.

How to get result in Java from native c++ Function defined with Qt(QJniEnvironment::RegisterNatives)

Okey... I read part of this book: https://www.informit.com/store/java-native-interface-programmers-guide-and-specification-9780201325775 and get some info.

jstring Widget::cppNativeFunction(JNIEnv *env, jobject obj) {
return (*env).NewStringUTF("Hello from C++/Qt!");
}
  • It's true. I finally see on my button "Java: Hello from C++/Qt!"

Android NDK RegisterNatives more full example

Going backwards from the RegisterNatives call in the first link, it hooks up native C++ methods to the following Java class:

package com.example.app.package;

class MyClass {
public native void nativeFoo();
public native bool nativeBar(String, int);
}

and it expects that you defined the following C++ functions earlier:

JNIEXPORT void JNICALL nativeFoo(JNIEnv *env, jobject object) { ... }
JNIEXPORT jboolean JNICALL nativeBar(JNIEnv *env, jobject object, jstring a, jint b) { ... }


Related Topics



Leave a reply



Submit