9

I'm trying to pass a structure as a pointer from JNI to Java to be able to pass it back later from Java to JNI. I have read this thread: Passing pointers between C and Java through JNI, but I did not succeed.

I have a pretty complex structure : struct myStruct_s myStruct;

From Java, I call a JNI function to initialize the structure and to return a long (pointer to the structure):

JNIEXPORT jlong JNICALL Java_example_ExampleJNI_getStruct(JNIEnv *jenv, jclass jcls) {
    struct myStruct_s mystruct;
    long *lp = (long*)&myStruct;
    return lp;
}

Then I call a Java method with that long in argument. In JNI I want to be able to use the strcuture created earlier. I do like this:

JNIEEXPORT jint JNICALL Java_example_ExampleJNI_methode1(JNIEnv *jenv, jclass jcls, jlong jarg) {
    struct myStruct_s *arg = (struct myStruct_s *)&jarg;
    ...
}

Well it doesn't work. I guess my cast of the long into the struct is wrong. How should I do it? Thank you.


EDIT : Thanks for the hints, here are the working functions

JNIEXPORT jint JNICALL Java_example_ExampleJNI_methode1(JNIEnv *jenv, jclass jcls, jlong jarg) {
    struct myStruct_s *arg;
    arg = (struct myStruct_s *)jarg;
    ...
} 

JNIEXPORT jlong JNICALL Java_example_ExampleJNI_getStruct(JNIEnv *jenv, jclass jcls) {
    struct myStruct_s *myStruct;
    myStruct = (struct myStruct_s *)malloc(sizeof(struct myStruct_s));
    long lp = (long)myStruct;
    return lp;
}
Community
  • 1
  • 1
leochab
  • 1,122
  • 4
  • 15
  • 28
  • 1
    Beware that `jlong`is not necessarily equal to `long` depending on the target platform. If you are running this on a platform where it is in fact a `long long`, this will fail, so you should always cast to `jlong`explicitly. – NeoNacho Apr 25 '13 at 13:50
  • leochab but how you will get access of strct object at Java layer. How to access local variable defined inside struct. Also is this possible to do same with some c++ class object. I''m following similar [here](http://stackoverflow.com/q/32840427/2624806). – CoDe Sep 29 '15 at 09:46

3 Answers3

5

In your example

struct myStruct_s mystruct;

is a local variable on the stack, and therefore not available after the function returns. Possubly that's just a cut-down of your code, but if not then use a malloc(sizeof(struct myStruct_s)) to get yourself a heap allocation.

That then raises the question of when you are going to free that allocation, watch out for memory leaks.

djna
  • 54,992
  • 14
  • 74
  • 117
4

The memory of this structure is destroyed after the method is returned because it was put into the stack, not into the heap, try it:

JNIEXPORT jlong JNICALL Java_example_ExampleJNI_getStruct(JNIEnv *jenv, jclass jcls) {
    long *lp = (long*)malloc(sizeof(struct myStruct_s));
    return lp;
}

Ps: why long* and not simple long?

Pih
  • 2,282
  • 15
  • 20
1

In additiona to @Moise's suggestion I would cast the pointer to a long ratehr than a long *

long lp = (long)&myStruct;
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130