Link to home
Start Free TrialLog in
Avatar of InteractiveMind
InteractiveMindFlag for United Kingdom of Great Britain and Northern Ireland

asked on

JNI Problem (some C/C++ expertise required please)

Hey,

I'm just learning to use JNI; I've created a few Shared Libraries, and have successfully linked them in with my Java Program. Now, I decided to start using C++ more for the main Native code (as opposed to C, which I'd been using so far); so, I've gone back to something very basic: The Java program passes a String to the Native function, which then prints it to the screen.
Here's my C++ Code:


// OutputImp.cpp

#include <jni.h>
#include "Output.h"
#include <string>
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_Output_print( JNIEnv *env, jobject obj, jstring msg )
{
    const char *str = (*env)->GetStringUTFChars( env, msg, 0 );   // Line 9
    string s( str );
    (*env)->ReleaseStringUTFChars( env, msg, str );                   // Line 11
   
    cout << s << endl;
   
    return;
}


I am using Dev-C++ for my C/C++ IDE. I've created a New "DLL" Project, and have added the above source (ObjectImp.cpp), and the Object.h Header File to the Project.
However, when I compile it, I'm getting these error messages:

           W:\Code\OutputImp.cpp       In function `void Java_Output_print(JNIEnv*, _jobject*,  _jstring*)':
    9     W:\Code\OutputImp.cpp       base operand of `->' has non-pointer type `JNIEnv_'
    11   W:\Code\OutputImp.cpp       base operand of `->' has non-pointer type `JNIEnv_'
          W:\Code\Makefile.win          [Build Error]  [OutputImp.o] Error 1

Why is this happening?? What is wrong with these lines:

    const char *str = (*env)->GetStringUTFChars( env, msg, 0 );   // Error  (line 9)
    (*env)->ReleaseStringUTFChars( env, msg, str );                    // Error  (line 11)

??  :o\

Kind Regards;
ASKER CERTIFIED SOLUTION
Avatar of Harisha M G
Harisha M G
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of InteractiveMind

ASKER

Hi,

That's spitting out even more errors. I'm going by here: http://java.sun.com/docs/books/tutorial/native1.1/implementing/string.html

But I can't see what I've done wrong... I even done those two lines in some C code earlier, with no problems.. :o\

Cheers.
#include <stdio.h>

struct myC
{
      int m;
};

int x(myC *envE)
{
      printf("%d",envE->m);
}

int main()
{
      myC b;
      x(&b);
}

will compile fine...

That means the syntax (*env)->
is wrong. Did you use env ->  ?

What are the errors ?

Please post the errors so that we can debug them
base operand of `->' has non-pointer type `JNIEnv_'

The thing is though, I used these lines of code earlier:

   const char *str = (*env)->GetStringUTFChars( env, msg, 0 );
   (*env)->ReleaseStringUTFChars( env, msg, str );

Without *any* problems. :o\
btw:
> "base operand of `->' has non-pointer type `JNIEnv_'"
is the error message.
Hmm, strange; when I create a 'C' Project, it is fine, the following compiles and runs fine (when implemented with my Java code):

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

JNIEXPORT void JNICALL Java_Output_print( JNIEnv *env, jobject obj, jstring prompt )
{
    const char *str = (*env)->GetStringUTFChars( env, prompt, 0 );
    printf( "%s", str );
    (*env)->ReleaseStringUTFChars( env, prompt, str );
   
    return;
}


However, when I try the following, as part of a C++ project:

#include <jni.h>
#include "Output.h"
#include <string>
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_Output_print( JNIEnv *env, jobject obj, jstring msg )
{
    const char *str = (*env)->GetStringUTFChars( env, msg, 0 );   // Line 9
    string s( str );
    (*env)->ReleaseStringUTFChars( env, msg, str );                   // Line 11
   
    cout << s << endl;
   
    return;
}


I get all those errors .... That's very strange.  :o\
Hmm... It would seem obvious to me, that it's down to the fact that:

    const char *str = (*env)->GetStringUTFChars( env, msg, 0 );
        // and
    (*env)->ReleaseStringUTFChars( env, msg, str );

only work with C. So, I shall have this thread closed, then ask a new thread in the C++ section... see if anyone knows of a way to convert a jstring into a string, in C++.

Cheers all the same.
btw, this does what I need:

#include <jni.h>
#include "Output.h"
#include <iostream>
#include <string>
using namespace std;

JNIEXPORT void JNICALL Java_Output_print( JNIEnv *env, jobject obj, jstring msg )
{
   const char* pb = env->GetStringUTFChars( msg, NULL);
   string s( pb );
   
   cout << s << endl;
   
   return;
}
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks guys,
I figured it out, it should be:

#include <jni.h>
#include "Output.h"
#include <iostream>
#include <string>
using namespace std;

JNIEXPORT void JNICALL Java_Output_print( JNIEnv *env, jobject obj, jstring msg )
{
   const char* pb = env->GetStringUTFChars( msg, NULL);
   string s( pb );
   
   cout << s << endl;
   
   return;
}

You lot were right about not using the (*env)-> for C++, but that failed to work previously, because the function call I was making:

   GetStringUTFChars( env, msg, 0 );

only seems to work with C, instead, I need to use this:

   GetStringUTFChars( msg, NULL);


..It's just a case of me figuring out the jni.h code I guess  ;o\  (and it's really not easy to make sense of nearly 2000 lines of someone elses, C & C++ code - especially when you haven't done much C/C++ for about a year! lol). Maybe I should save up some money and buy a book on it..

Well, I may as well just split the points between you guys; as I very much appreciate the help :-)

Kind Regards;
Avatar of CajunBill
CajunBill

Thanks, IM, glad we could help.

Harish certainly deserved the credit for pointing out the *env issue.
I guess I missed the original post about that, although I can't see how.

I certainly don't want to be one of those "experts" that inflates their points by cheap tactics, like posting in every possible thread or presenting someone else's answer as their own.

If you think I helped, thanks for the points.  Otherwise, give them to Harish.
Sincerely,
CajunBill
Hi CajunBill,

You certainly elaborated a bit further than Harish did, so I thank you.. Also, the actual solution I found was thanks to me being flukey enough to locate the required function in the JNI header -- so I don't feel that you deserve any less points than anyone else.  :-)

Regards;
Rob.