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
Nextdouble() Throws an Inputmismatchexception When I Enter a Double
Difference Between "Char" and "String" in Java
How to Format Localdate to String
Should You Always Code to Interfaces in Java
Mocking Files in Java - Mock Contents - Mockito
Performance Concurrenthashmap VS Hashmap
Java Simpledateformat Timezone Offset with Minute Separated by Colon
How to Set Hard Limit on a Jcomponent When Setmaximumsize() and Setprefferedsize() Don't Work
Setter Methods or Constructors
How to Launch Ie Browser Using Selenium2 (Webdriver) with Java
Spring - Redirect After Post (Even with Validation Errors)
Can't a Swing Component Be Added to Multiple Containers
What Is the Best/Simplest Way to Read in an Xml File in Java Application