extern "C". mandatory or not?

1,228 views
Skip to first unread message

Alexander

unread,
Jan 2, 2011, 7:04:27 PM1/2/11
to android-ndk
hi all.
i'm a little confused with this, i have compiled several samples with
the ndk with no problems,
but it all was "pure" C. now i'm starting to import C++ specifics libs
(using opengl es) and i'm having some
strange results.

for one side, i've read that you have to specify extern "C" at least
on the native definitions that are called
from the JNI. but i dont know exactly how this works, i mean, whats
the correct way of mix the C/C++, take for example:

extern "C" {

void Java_ndk_tests_MRenderer_nativeInit(JNIEnv* env) {
appInit(env);
}

... and you have that appInit in some other file, and mixed with c++
object initializations, etc.. do you have to add the extern "C"
directly in all places?.
i'll really appreciate some light on this.

Mike Edenfield

unread,
Jan 2, 2011, 9:08:43 PM1/2/11
to andro...@googlegroups.com, Alexander
On 1/2/2011 7:04 PM, Alexander wrote:

> for one side, i've read that you have to specify extern "C" at least
> on the native definitions that are called
> from the JNI. but i dont know exactly how this works, i mean, whats
> the correct way of mix the C/C++, take for example:

If you want the JNI to locate your native functions
automatically, they have to match the expected function
signatures exactly. C++ function names get mangled by the
compiler (to support overloading and other things) -- unless
you specify extern "C". If you forget the extern
declaration, JNI will be unable to find the function
implementations to match your Java "native" declarations.

If you use javah -jni, which you absolutely should already
be doing, it takes care of this whole mess for you.

But a much better option is to skip the whole problem and
tell JNI where to find your function implementations. This
is accomplished using the RegisterNatives() method of the
JNIEnv object. It's a tiny bit more work to set up but
(IMO) is a much better way to go.

I posted an example of how to do this a couple of weeks ago.

http://groups.google.com/group/android-ndk/msg/4a615e23673feef7

It's in C, not C++, but the idea is the same. In C++,
JavaVM and JNIEnv are classes, so you can call methods on it
directly. That is, a call like this in C:

jclass cls = (*env)->FindClass(env, JAVA_CLASS);

becomes this in C++:

jclass cls = env->FindClass(JAVA_CLASS);

(There's also a more complete example of how to do this in
the Android PDK:

http://android.git.kernel.org/?p=platform/development.git;
a=blob_plain;f=pdk/pndk/samples/samplejni/native.cpp;hb=HEAD

but not in the NDK itself, which I find odd.)

--Mike


Reply all
Reply to author
Forward
0 new messages