Reputation: 2381
I am passing the current activity to the native method using Java Native Interface on android. But I am not doing it using JNI like function names. I am registering native functions manually.
This works (JNI naming).
com_venkatesh_home.c
JNIEXPORT void JNICALL Java_com_venkatesh_Home_doStuff(JNIEnv *env, jobject activity) {
jclass Activity = (*env)->GetObjectClass (env, activity);
com.venkatesh.Home.java
private native void doStuff();
static {
System.loadLibrary("venkatesh");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
doStuff();
}
But this does not work. (Manual registration and passing activity as an object)
me.c
static JavaVM *java_vm;
void do_stuff (jobject activity)
{
JNIEnv *env;
if ((*java_vm)->GetEnv(java_vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
LOG_D("GetEnv failed");
return -1;
}
jclass Activity = (*env)->GetObjectClass (env, activity);
}
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
java_vm = vm;
JNIEnv* env;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
LOG_D ("GetEnv failed.");
return -1;
}
// Find the class calling native function
jclass Home = (*env)->FindClass(env, "com/venkatesh/Home");
if (Home == NULL) {
LOG_D ("FindClass failed : No class found.");
return -1;
}
// Register native method for getUsbPermission
JNINativeMethod nm[1] = {
{ "doStuff", "(Landroid/app/Activity;)V", do_stuff}
};
if ((*env)->RegisterNatives(env, NativeUsb, nm , 1)) {
LOG_D ("RegisterNatives Failed.");
return -1;
}
return JNI_VERSION_1_6;
}
com.venkatesh.Home.java
private native void doStuff(Activity activity);
static {
System.loadLibrary("venkatesh");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
doStuff(this);
}
The error is
JNI WARNING: 0xb89a7788 is not a valid JNI reference (GetObjectClass)
where 0xb89a7788 is the "this" received on jni side as activity.
Now, as I understand this represents the present object. Equivalent to self in python. But then I am passing an object to the native side and hence it should be a valid reference. Why the invalid reference error? It this not an object? What is wrong?
Upvotes: 0
Views: 541
Reputation: 2825
This is happening not because of how the method is being registered, but because of the signature of your native method. I would rewrite that method like this:
void do_stuff (JNIEnv *env, jobject this, jobject activity)
{
jclass Activity = (*env)->GetObjectClass (env, activity);
// ...and whatever else you want...
}
Every JNI method must take a JNIEnv *
as its first parameter. (Note also the lack of the static
env
variable - it isn't needed). Also, since it is not a static method, the first parameter passed in to the method will be this
and not activity
.
Upvotes: 3