Android中JNI调用时Java传递参数值异常问题排查
JNI参数值与Java传入不一致的问题解决
核心问题是Java端native方法的参数类型和JNI函数的参数类型不匹配:
- Java端声明的是
Integer包装类参数 - JNI函数里却用了对应Java基本类型
int的jint来接收
这种类型不匹配会导致JNI调用时参数栈错位,把对象的内存地址当成基本类型值解析,所以得到的是随机垃圾值,其他类型(如String、Long等)也会因为同样的逻辑出现异常。
解决方法有两种:
方法1:改用基本类型匹配(推荐,更高效)
修改Java端的native方法声明,把Integer换成基本类型int:
public native void setIA(int model);
调用代码保持setIA(1);不变,JNI原代码无需修改,类型匹配后就能正确获取参数值。
方法2:保留包装类,JNI端手动解包
如果业务必须使用Integer包装类,JNI函数需要接收jobject类型参数,再通过JNI API解析出包装类里的基本类型值:
extern "C" JNIEXPORT void JNICALL Java_com_sfy_vitaltechnics_Utils_Parameters_setIA(JNIEnv *env, jobject thiz, jobject modelObj) { // 获取Integer类的intValue()方法ID jclass integerCls = env->FindClass("java/lang/Integer"); jmethodID intValueMethod = env->GetMethodID(integerCls, "intValue", "()I"); // 调用intValue()获取实际的int值 jint model = env->CallIntMethod(modelObj, intValueMethod); LOGD( "This is a number from JNI: %d", model ); // 释放局部引用(规范操作,避免内存泄漏) env->DeleteLocalRef(integerCls); }
注意事项
所有JNI参数都必须严格对应:
- Java基本类型 ↔ JNI基本类型(如int↔jint, long↔jlong, float↔jfloat)
- Java引用类型(包括包装类、String、自定义对象) ↔ JNI的jobject(或子类jstring、jclass等)
内容的提问来源于stack exchange,提问作者Clamore
相关产品推荐
相关产品推荐

