JNI中RegisterNatives动态注册函数报错,AS提示无法解析对应JNI函数
JNI动态注册错误的问题排查与修复
核心错误点汇总
- 函数名大小写不匹配:Java层的
funcall与Native层的funCall大小写不一致,导致Android Studio无法关联对应函数。 - JNI方法签名完全错误:
JNINativeMethod数组中的签名与Java方法的实际签名不匹配,同时Native函数的参数、返回值和Java层定义不对应。 - C++函数名 mangling 问题:C++编译会自动修改函数名,未用
extern "C"包裹JNI函数,可能导致动态注册时找不到正确的函数地址。 - JNI_OnLoad代码错误:
GetEnv参数传递错误、FindClass拼写错误。 - Native函数不符合JNI规范:非静态Native方法必须包含
JNIEnv*和jobject参数,你的npfuncall缺少这两个参数。
分步修复方案
1. 对齐函数名与JNI签名
Java层方法名必须和Native层函数名完全一致,同时JNI签名严格对应Java方法的参数和返回值:
- Java的
public native void funcall(int i):签名为(I)V(参数int,返回void),对应Native函数需定义为void funcall(JNIEnv*, jobject, jint)。 - Java的
public native int npfuncall():签名为()I(无参数,返回int),对应Native函数需定义为int npfuncall(JNIEnv*, jobject)。
2. 解决C++函数名 mangling
在Native函数的声明和定义外包裹extern "C",避免C++编译器修改函数名:
extern "C" { void funcall(JNIEnv *env, jobject obj, jint i); int npfuncall(JNIEnv *env, jobject obj); }
3. 修正JNI_OnLoad中的错误
GetEnv需要传递jniEnv的地址:vm->GetEnv((void **)&jniEnv, JNI_VERSION_1_6)- 修正拼写错误:
FindCalss改为FindClass - 添加错误检查,提升代码健壮性
4. 修正Native函数的参数与返回值
确保Native函数参数符合JNI规范,返回值与Java层定义一致:
funcall返回值改为void,保留JNIEnv*、jobject、jint参数npfuncall添加JNIEnv*和jobject参数
修改后的完整Native代码
#include <jni.h> #include <android/log.h> extern "C" { void funcall(JNIEnv *env, jobject obj, jint i); int npfuncall(JNIEnv *env, jobject obj); } static const JNINativeMethod jniNativeMethod[] = { {"funcall", "(I)V", (void*)funcall}, {"npfuncall", "()I", (void*)npfuncall} }; static const char CLASS_NAME[] = "com/example/nativecpp/MainActivity"; jint JNI_OnLoad(JavaVM *vm, void * reserved) { __android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "JNI_OnLoad Function Call"); JNIEnv *jniEnv = nullptr; // 修正GetEnv参数传递方式 if(vm->GetEnv((void **)&jniEnv, JNI_VERSION_1_6) != JNI_OK) { return -1; } __android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "vm->GetEnv Call"); // 修正FindClass拼写错误 jclass javaclass = jniEnv->FindClass(CLASS_NAME); if (javaclass == nullptr) { __android_log_print(ANDROID_LOG_ERROR, "JNI_TAG", "Failed to find target class"); return -1; } __android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "jniEnv->FindClass Call"); // 添加RegisterNatives错误检查 jint result = jniEnv->RegisterNatives(javaclass, jniNativeMethod, sizeof(jniNativeMethod)/sizeof(JNINativeMethod)); if (result != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, "JNI_TAG", "RegisterNatives failed: %d", result); return -1; } __android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "jniEnv->RegisterNatives Call"); return JNI_VERSION_1_6; } extern "C" { void funcall(JNIEnv *env, jobject obj, jint i) { __android_log_print(ANDROID_LOG_INFO, "funcall", "function called: %d",i); } int npfuncall(JNIEnv *env, jobject obj) { __android_log_print(ANDROID_LOG_INFO, "npfuncall", "function called"); return 0; } }
Java层注意事项
静态块中加载了两个库nativecpp和dynamic-lib,确认dynamic-lib是业务必需的,否则可移除;另外stringFromJNI需确保有对应的Native实现或动态注册逻辑,避免运行时报错。
内容的提问来源于stack exchange,提问作者lcwstudio
相关产品推荐
相关产品推荐

