How to pass C structs back and forth to Java code in JNI?

后端 未结 4 1916
一向
一向 2020-11-27 10:58

I\'ve got some C functions which I am calling through JNI which take a pointer to a structure, and some other functions which will allocate/free a pointer to the same type o

相关标签:
4条回答
  • 2020-11-27 11:27
    1. Make the class on both the Java and C++ sides, just putting in the member variables. C++ structs are really just classes with public data members. If you are really in pure C, stop reading now.
    2. Use your IDE(s) to make setters and getters for the member variables automatically.
    3. Use javah to generate the C header file from the Java class.
    4. Do some editing on the C++ side to make the setters and getters match the generated header file.
    5. Put in the JNI code.

    This is not an ideal solution, but it may save you a little time, and it will at least give you a skeleton that you can edit. This functionality could be added to an IDE, but without a big demand, it probably won't happen. Most IDEs don't even support mixed language projects, let alone having them talk to each other.

    0 讨论(0)
  • 2020-11-27 11:37

    C structure is the collection of variables (some are function pointer). Pass to java is not a good idea. In general, it is the problem how to pass more complex type to java, like pointer.

    In JNI book, to keep the pointer/structure in native and export manipulation to java is recommended. You can read some useful articles. The JavaTM Native Interface Programmer's Guide and Specification, I have read. 9.5 Peer Classes have a solution to deal with it.

    0 讨论(0)
  • 2020-11-27 11:45

    It's crashing because Java_com_myorg_MyJavaClass_createNewMyStruct is declared to return jobject, but is actually returning struct MyStruct. If you ran this with CheckJNI enabled, the VM would complain loudly and abort. Your processData() function is also going to be fairly upset about what it gets handed in arguments.

    A jobject is an object on the managed heap. It can have extra stuff before or after the declared fields, and the fields don't have to be laid out in memory in any particular order. So you can't map a C struct on top of a Java class.

    The most straightforward way to deal with this was identified in an earlier answer: manipulate the jobject with JNI functions. Allocate the objects from Java or with NewObject, Get/Set the object fields with appropriate calls.

    There are various ways to "cheat" here. For example, you could include a byte[] in your Java object that holds sizeof(struct MyStruct) bytes and then use GetByteArrayElements to get a pointer to it. A bit ugly, especially if you want to access the fields from the Java side as well.

    0 讨论(0)
  • 2020-11-27 11:51

    You need to create a Java class with the same members as C struct, and 'map' them in the C code via methods env->GetIntField, env->SetIntField, env->GetFloatField, env->SetFloatField, and so on - in short, lots of manual labor, hopefully there already exist programs that do it automatically: JNAerator (http://code.google.com/p/jnaerator) and SWIG (http://www.swig.org/). Both have their pros and cons, the choice is up to you.

    0 讨论(0)
提交回复
热议问题