JNI Java <-> native Struct
class StructPass
{
public native void toNativeStruct();
public native void fromNativeStruct();
public native void initNative();
private String name;
private int age;
private float height;
static {
System.loadLibrary("jni");
}
public StructPass(String n, int a, float h)
{
name = n;
age = a;
height = h;
}
public static void main(String[] args)
{
StructPass hello = new StructPass(new String("kerker"), 10, 180);
hello.initNative();
hello.toNativeStruct();
hello.fromNativeStruct();
System.out.println("In Java:");
System.out.println(" hello.name = \"" + hello.name + "\"");
System.out.println(" hello.age = " + hello.age);
System.out.println(" hello.height = " + hello.height);
}
}
編譯 java
javac StructPass.java
javah -jni StructPass
#include <jni.h>
#ifndef _Included_StructPass
#define _Included_StructPass
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_StructPass_toNativeStruct
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_StructPass_fromNativeStruct
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_StructPass_initNative
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
#include "StructPass.h"
static struct {
jfieldID name;
jfieldID age;
jfieldID height;
} gStructPassClassInfo;
JNIEXPORT void JNICALL Java_StructPass_toNativeStruct
(JNIEnv* env, jobject obj)
{
jstring jstr;
int age;
float height;
const char* str;
printf("In C:\n");
jstr = (jstring)(*env)->GetObjectField(env, obj, gStructPassClassInfo.name);
str = (*env)->GetStringUTFChars(env, jstr, NULL);
age = (*env)->GetIntField(env, obj, gStructPassClassInfo.age);
height = (*env)->GetFloatField(env, obj, gStructPassClassInfo.height);
if (str == NULL) {
return;
}
printf(" c.name = \"%s\"\n", str);
printf(" c.age = %d\n", age);
printf(" c.height = %f\n", height);
(*env)->ReleaseStringUTFChars(env, jstr, str);
}
JNIEXPORT void JNICALL Java_StructPass_fromNativeStruct
(JNIEnv* env, jobject obj)
{
jstring jstr;
jstr = (*env)->NewStringUTF(env, "123");
(*env)->SetObjectField(env, obj, gStructPassClassInfo.name, jstr);
(*env)->SetIntField(env, obj, gStructPassClassInfo.age, 18);
(*env)->SetFloatField(env, obj, gStructPassClassInfo.height, 179.0);
}
JNIEXPORT void JNICALL Java_StructPass_initNative
(JNIEnv* env, jobject obj)
{
jclass cls = (*env)->GetObjectClass(env, obj);
gStructPassClassInfo.name = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;");
gStructPassClassInfo.age = (*env)->GetFieldID(env, cls, "age", "I");
gStructPassClassInfo.height = (*env)->GetFieldID(env, cls, "height", "F");
}
gcc -fPIC -Wall -I /usr/lib/jvm/java-8-openjdk-amd64/include/ -I /usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -shared -o libjni.so StructPass.c
Run
java -Djava.library.path=. StructPass
In C:
c.name = "kerker"
c.age = 10
c.height = 180.000000
In Java:
hello.name = "123"
hello.age = 18
hello.height = 179.0