Reputation: 1698
I have to pass a structure
struct Info {
u_int8_t timestamp[8];
u_int32_t a;
u_int32_t b;
u_int32_t c;
ActiveInfo activeInfo[MAX_ACTIVE_SET];
};
struct ActiveInfo
{
u_int8_t is_reference;
u_int16_t p;
u_int32_t q;
u_int8_t r;
u_int8_t s;
};
typedef struct ActiveInfo ActiveInfo;
I want to pass this (Info) structure to my java code.I have goggled,but not get complete ways to do this.
Thanks.
Upvotes: 3
Views: 7537
Reputation: 57173
You already know that the mapping works only one way: you can access a Java class from C/C++, but not vice versa.
But it's also important to remember that such mapping involves significant overhead - both in memory used, and in CPU.
Therefore it may be wize to give up on complete transparency. For example, if you only need to read activeInfo[n].s, you can write a native method getais(int n). Or uou can receive the whole structure in java as a DirectByteBuffer, calculate the required offset, and manipulate the value directly.
Upvotes: 1
Reputation: 7293
The structure must be defined at Java side, as a class with members. The fact is that JNI allows C to access Java objects, but not Java to access C objects (structs). So if you want to "pass" something through JNI and have it accessible on both sides, it must be a Java object, then qualified as jobject
in the interface. From C side then, you have two options:
GetFieldID()
and Get/Set<Type>Field
, though it's more complicated with arrays (you got some i see)Invoke<Retval>Method
It depends on design of your data storage. You perhaps want only one side (C or Java) to read and the other to write, which can be reflected in the design conveniently.
Edit:
Example can be found at site pointed out by @asgoth : www.steveolyo.com. There is a chapter named "Passing C Structures from C to Java" but then it silently explains how to reflect requried C structure in Java class and pass Java object into C via JNI - which is exactly what my response says.
Upvotes: 5
Reputation: 35829
You need a JNIEXPORT:
JNIEXPORT jint JNICALL
Java_FillCStruct
(
JNIEnv *env,
jclass obj,
jobject info // EntryInformation object instantiation
)
{
testInfo entryInfo;
jclass clazz;
jfieldID fid;
jmethodID mid;
GetInfo(entryInfo); // fills in the entryInfo
clazz = (*env)->GetObjectClass(env, info);
if (0 == clazz)
{
printf("GetObjectClass returned 0\n");
return(-1);
}
fid = (*env)->GetFieldID(env,clazz,"index","I");
// This next line is where the power is hidden. Directly change
// even private fields within java objects. Nasty!
(*env)->SetIntField(env,info,fid,testInfo.index);
...
Here is a site with some examples: http://www.steveolyo.com/JNI/JNI.html
Upvotes: 3