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
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