如何通过JNI将C语言结构体传递给Java并映射对象属性
JNI中实现C结构体到Java对象的赋值
我来一步步教你怎么把C结构体里的值传到Java对象里,下面是具体的实现步骤和完整代码:
完整JNI实现代码
#include <jni.h> #include <string.h> #include <stdlib.h> // 如果JNI文件没关联对应的C头文件,先声明结构体和创建函数 struct MyEntity { char *_myEntityType; }; struct MyEntity my_C_Entity(); extern "C" JNIEXPORT jobject JNICALL Java_myproject_1_FromCPP__1main(JNIEnv *env, jobject instance) { // 1. 调用C函数拿到结构体实例 struct MyEntity cEntity = my_C_Entity(); // 2. 获取Java端MyEntity类的引用 jclass myEntityClass = env->FindClass("myproject/MyEntity"); if (myEntityClass == NULL) { return NULL; // 找不到类直接返回 } // 3. 获取MyEntity的无参构造方法ID(你的Java类默认有无参构造) // 方法签名()V表示无参数、返回值为void jmethodID constructor = env->GetMethodID(myEntityClass, "<init>", "()V"); if (constructor == NULL) { env->DeleteLocalRef(myEntityClass); // 提前释放局部引用 return NULL; } // 4. 创建Java端MyEntity对象实例 jobject javaEntity = env->NewObject(myEntityClass, constructor); if (javaEntity == NULL) { env->DeleteLocalRef(myEntityClass); return NULL; } // 5. 获取set_myEntityType方法的ID // 方法签名(Ljava/lang/String;)V表示参数是String、返回值为void jmethodID setMethod = env->GetMethodID(myEntityClass, "set_myEntityType", "(Ljava/lang/String;)V"); if (setMethod == NULL) { env->DeleteLocalRef(myEntityClass); env->DeleteLocalRef(javaEntity); return NULL; } // 6. 把C字符串转换成Java的String对象 jstring jType = env->NewStringUTF(cEntity._myEntityType); if (jType == NULL) { env->DeleteLocalRef(myEntityClass); env->DeleteLocalRef(javaEntity); free(cEntity._myEntityType); // 释放strdup分配的内存,避免泄漏 return NULL; } // 7. 调用set方法给Java对象赋值 env->CallVoidMethod(javaEntity, setMethod, jType); // 8. 清理资源:释放局部引用和C层的动态内存 env->DeleteLocalRef(myEntityClass); env->DeleteLocalRef(jType); free(cEntity._myEntityType); // 因为my_C_Entity用了strdup,必须手动释放 // 返回赋值完成的Java对象 return javaEntity; }
几个必须注意的细节:
- 方法签名:JNI调用Java方法必须用正确的签名,你可以通过
javap -s myproject.MyEntity命令生成官方签名,确保和代码里的一致。 - 局部引用释放:虽然JNI函数返回时会自动释放局部引用,但如果有分支提前返回,最好手动释放,避免内存泄漏。
- 内存管理:
my_C_Entity()里用strdup分配的内存,JNI不会帮你回收,必须用free手动释放,否则会造成内存泄漏。 - 错误检查:每一步JNI调用后都做NULL检查,避免空指针导致程序崩溃。
内容的提问来源于stack exchange,提问作者Program-Me-Rev
相关产品推荐
相关产品推荐

