tags:

views:

329

answers:

4

Hey Folks,

So i have the following code in C that utilizes Java Native Interface however i would like to convert this to C++ but am not sure how.

 #include <jni.h>
 #include <stdio.h>
 #include "InstanceMethodCall.h"

 JNIEXPORT void JNICALL 
 Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj)
 {
     jclass cls = (*env)->GetObjectClass(env, obj);
     jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");
     if (mid == NULL) {
         return; /* method not found */
     }
     printf("In C\n");
     (*env)->CallVoidMethod(env, obj, mid);
 }

Java Program:

 class InstanceMethodCall {
     private native void nativeMethod();
     private void callback() {
         System.out.println("In Java");
     }
     public static void main(String args[]) {
         InstanceMethodCall c = new InstanceMethodCall();
         c.nativeMethod();
     }
     static {
         System.loadLibrary("InstanceMethodCall");
     }
 }

What are the differences in which JNI interacts with C and C++? Any help is greatly appreciated.

Thanks, Pete

A: 

The first code a correct C++, isn't it? So, you're done!

Seriously, what do you want to change in that code? Why?

alamar
when i compile the above code with as .c it works and runs fine, change it to .cpp and i get a slew of errors
Petey B
Then post the errors so we can see what it is we're supposed to answer? ;)
jalf
The code he posted is C code, and JNI + C requires pointers. When linking Java and C++, however, JNI provides /objects/ - rather than "pointers to structs which behave like objects" - to the native language.
rascher
+4  A: 

Have you tried wrapping your C code in an extern "C". See C++ Faq Lite for more information, and for other possible mechanisms to let you use your C code with C++.

Brian
I think that's probably the issue. JNI expects C code, so he's probably getting linking errors.
Michael Myers
Yarp. Names are probably getting mangled in the C++ compiler. Add the extern C { <your code> }.
Kieveli
+1  A: 

It's been a while since I touched standard C++ but I'm gonna try it anyway.

"(*env)->" looks weird to me. Shouldn't that simply be "env->" ?

Maybe I'm wrong and it is supposed to work, but why make things more complicated anyways?

QuickRecipesOnSymbianOS
x->y is shorthand for (*x).y. Therefore, (*env)->y is equivalent to (**env).y, which is different from (*env).y: there is an extra dereference occurring.
Adam Rosenfield
The dereference syntax, I actually knew. Let me be more clear: I'm just far from convinced the C++ version of JNIEnv actually requires the double dereferencing.
QuickRecipesOnSymbianOS
+2  A: 

I used to have the book Essential JNI. And while it is kinda dated, much of it still works today.

If I recall correctly, in C, Java constructs are simply pointers. Thus, in your code, "(*env)->" is dereferencing pointers to give you access to the underlying methods.

For C++, "env" is actually an object - a different entity than a C pointer. (And JNI can actually provide real objects for your C++ code to manipulate, since C++ actually supports objects.) So "env->" has a different meaning in C++, it means "call the method that is contained in the object pointed to by "env".

The other difference, I believe, is that many of the C-JNI functions require that one of your parameters be the "JNIEnv *env". So in C you might have to say (*env)->foo(env, bar). With c++, the second reference to "env" is not necessary, so you can instead say "env->foo(bar)"

Unfortunately, I don't have the above book in front of me, so I can't quite confirm this! But I think investigating those two things (specifically looking for them on google or in other JNI code) will get you pretty far.

rascher
So JNI can actually handle both C and C++? I didn't know that (but maybe that's not surprising, since I've never used JNI :p).
Michael Myers
(haha, ty for fixing my markdown!)Yep; the interface behaves the same way - the C vs C++ code is /basically/ isomorphic, and in practice the only difference is syntax.
rascher