?
Solved

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

Posted on 2005-04-24
14
Medium Priority
?
2,459 Views
Last Modified: 2013-11-23
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;
0
Comment
Question by:InteractiveMind
  • 8
  • 3
  • 2
  • +1
14 Comments
 
LVL 37

Accepted Solution

by:
Harisha M G earned 800 total points
ID: 13854414
Hi InteractiveMind,
> (*env)->

env ->


Bye
---
Harish
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13854432
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.
0
 
LVL 37

Expert Comment

by:Harisha M G
ID: 13854485
#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 ?

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 37

Expert Comment

by:Harisha M G
ID: 13854516
Please post the errors so that we can debug them
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13854552
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\
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13854554
btw:
> "base operand of `->' has non-pointer type `JNIEnv_'"
is the error message.
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13854656
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\
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13854850
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.
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13854903
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;
}
0
 
LVL 7

Assisted Solution

by:CajunBill
CajunBill earned 800 total points
ID: 13856244
Hi IM,
in C++ try using either (env)->  or "*env."
Perhaps the problem is that you are using "->" which requires a pointer, but you are basing it on "*env", that de-references the pointer into a non-pointer.
I'll look in the C++ thread to see if you have posted there.
HTH
CajunBill
0
 
LVL 3

Assisted Solution

by:Mig-O
Mig-O earned 400 total points
ID: 13856618
try to embrace your code with "extern C { ... }" if you use c++!
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13857715
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;
0
 
LVL 7

Expert Comment

by:CajunBill
ID: 13858656
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
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 13858734
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.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month15 days, 17 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question