Reputation: 16038
My C code does not manage to find the public static function call I have in Java. It manages to find the class without error.
I am attempting to return a result to a callback method onResponse
. "5" will be replaced by something more complex later.
I have seem similar questions on StackOverflow, but no changes so far seem to have helped. Perhaps I have a logic error?
My JNI (updated #2):
void cec_debug_msg(JNIEnv *env, cec_rx_message_t* msg) {
jclass cls = (*env)->FindClass(env, "com/example/utils/CECUtils");
if(!cls) {
LOGE("Could not find the CEC class.");
} else {
jmethodID methodid = (*env)->GetStaticMethodID(env, cls, "onResponse", "(I)V");
if(!methodid) {
// Code always reaches this point, never finding the method
LOGE("Could not find the callback method.");
} else {
LOGV("Called static void method.");
(*env)->CallStaticVoidMethod(env, cls, methodid, 5);
}
}
}
This code is contained in a method that is called from this function:
JNIEXPORT int JNICALL Java_com_example_utils_CECUtils_startListening(JNIEnv *env, jclass cls) {
...
cec_debug_msg(env, &rx_msg);
...
}
My Java (updated #1):
public class CECUtils {
static {
System.loadLibrary("cecutils");
}
public static native int startListening();
...
public static void onResponse(int opcode) {
Utils.log("CEC", "From JNI!");
}
}
Signature check:
javap -s -p CECUtils
public static void onResponse(int);
Signature: (I)V
-keep public class com.example.utils.CECUtils {
*;
}
Upvotes: 4
Views: 16178
Reputation: 9422
see the method signatures (http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html)
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V"); the (I)V determines the signature
Here is the docs of GetMethodID:
GetMethodID
jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
Returns the method ID for an instance (nonstatic) method of a class or interface. The method may be defined in one of the clazz’s superclasses and inherited by clazz. The method is determined by its name and signature.
GetMethodID() causes an uninitialized class to be initialized.
To obtain the method ID of a constructor, supply as the method name and void (V) as the return type.
maybe you can use javap to determine the signature of your method:
Using javap to Generate Method Signatures
To eliminate the mistakes in deriving method signatures by hand, you can use the javap tool to print out method signatures. For example, by running:
javap -s -p Prompt
you can obtain the following output:
Compiled from Prompt.java class Prompt extends java.lang.Object /* ACC_SUPER bit set */ { private native getLine (Ljava/lang/String;)Ljava/lang/String; public static main ([Ljava/lang/String;)V <init> ()V static <clinit> ()V }
The "-s" flag informs javap to output signatures rather than normal Java types. The "-p" flag causes private members to be included.
Upvotes: 5
Reputation: 992
Try using GetStaticMethodID
instead of GetMethodID
.
Note, you will need to call CallStaticVoidMethod
instead of CallVoidMethod
also.
See here for more info: http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html
Upvotes: 7