JNI: C vs C++

  • Thread starter Peter Jay Salzman
  • Start date
P

Peter Jay Salzman

I'm reading chapter 3 of Sheng Liang's "The JNI Programmer's Guide and
Specification", and am working the "Prompt" example. I'm working through the
examples using gcc on GNU/Linux and VC++ on MS Windows. Here's the C code in
Sheng's book:


JNIEXPORT jstring JNICALL
Java_Prompt_getLine( JNIEnv *env, jobject obj, jstring prompt )
{
char buf[128];
const jbyte *str;

str = (*env)->GetStringUTFChars( env, prompt, NULL );
if ( str == NULL ) return NULL;

printf("%s", str);
(*env)->ReleaseStringUTFChars(env, prompt, str);

scanf("%s", buf);
return (*env)->NewStringUTF(env, buf);
}


The code compiled with gcc, but with VC++, all hell broke loose. The VC++
errors looked like:

left of '->NewStringUTF' must point to class/struct/union type is
'JNIEnv' did you intend to use '.' instead?

which sounds like (*env) isn't a pointer, which it should be if I'm going to
compute "(*env)->". On a whim, I changed (*env) to env. Maybe env itself
is the pointer:


JNIEXPORT jstring JNICALL
Java_Prompt_getLine( JNIEnv *env, jobject obj, jstring prompt )
{
char buf[128];
const jbyte *str;

str = env->GetStringUTFChars( env, prompt, NULL );
if ( str == NULL ) return NULL;

printf("%s", str);
env->ReleaseStringUTFChars(env, prompt, str);

scanf("%s", buf);
return env->NewStringUTF(env, buf);
}


Now the errors were:

'JNIEnv_::GetStringUTFChars' : function does not take 3 arguments
'JNIEnv_::ReleaseStringUTFChars' : function does not take 3 arguments
'JNIEnv_::NewStringUTF' : function does not take 2 arguments

which reminds me of implicit argument passing in C++. Maybe the env
argument is passed implicitly? So I got rid of it:


JNIEXPORT jstring JNICALL
Java_Prompt_getLine( JNIEnv *env, jobject obj, jstring prompt )
{
char buf[128];
const jbyte *str;

str = env->GetStringUTFChars( prompt, NULL );
if ( str == NULL ) return NULL;

printf("%s", str);
env->ReleaseStringUTFChars( prompt, str );

scanf("%s", buf);
return env->NewStringUTF( buf );
}


Eureka. Now the errors look like:

Prompt.cpp(17) : error C2440: '=' : cannot convert from 'const char *'
to 'const jbyte *' Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast

Prompt.cpp(21) : error C2664: 'JNIEnv_::ReleaseStringUTFChars' : cannot
convert parameter 2 from 'const jbyte *' to 'const char *' Types
pointed to are unrelated; conversion requires reinterpret_cast,
C-style cast or function-style cast


Again, on a lark, I changed

const jbyte *str;

to

const char *str;


Now it compiled fine.


Although the book I'm reading doesn't say so, I'm going to assume that JNI
behaves differently for C and C++, and that VC++ by default, "looks" like C++
to JNI.

I don't see anywhere in this book that talks about the differences between C
and C++ for JNI. Most of my changes to the code was educated guesswork, but
that only takes one so far. How are the readers supposed to learn how to use
JNI with C++ if the syntax is so different but not explained in the book?

And is there a way of forcing VC++ to "look" like plain C to JNI?

Thanks!
Pete
 
G

Gordon Beaton

Although the book I'm reading doesn't say so, I'm going to assume
that JNI behaves differently for C and C++, and that VC++ by
default, "looks" like C++ to JNI.

I don't see anywhere in this book that talks about the differences
between C and C++ for JNI. Most of my changes to the code was
educated guesswork, but that only takes one so far. How are the
readers supposed to learn how to use JNI with C++ if the syntax is
so different but not explained in the book?

It's mentioned in section 8.6:
http://java.sun.com/docs/books/jni/html/other.html

It's also here in the JNI spec:
http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp715
And is there a way of forcing VC++ to "look" like plain C to JNI?

Perhaps VC++ can compile C programs, and if that's the case the VC++
documentation should be able to tell you how. Perhaps it makes
assumptions based on the source file extension or the command line
options you used.

/gordon
 
C

Chris Uppal

Peter said:
The code compiled with gcc, but with VC++, all hell broke loose.

If you trace through <jni.h> you'll see that JNIEnv is defined differently
depending on whether you are using the C or C++ API.

Almost certainly the compiler is somehow being confused about whether you are
writing C++ or C (as you already realise). A line like

str = (*env)->GetStringUTFChars( env, prompt, NULL );

is using the C interface (the giveaway is that the 'env' parameter has to be
passed to the function). I don't use C++ with JNI (actually I don't use C
either), but I think the equivalent code, using the C++ API would be:

str = env->GetStringUTFChars( prompt, NULL );

As far as I know, the principle way that VC distinguishes between C and C++ is
the file extension (.c definitely means 'C', .cpp definitely means 'C++', I
have no idea about other extensions such as .cxx). In VS.2003 there is a flag
(somewhere!) which can override the defaults on a per-file basis.

But the bottom line is: don't put 'C' code in a file with a .cpp extension ;-)

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top