You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNI中RegisterNatives动态注册函数报错,AS提示无法解析对应JNI函数

JNI动态注册错误的问题排查与修复

核心错误点汇总

  1. 函数名大小写不匹配:Java层的funcall与Native层的funCall大小写不一致,导致Android Studio无法关联对应函数。
  2. JNI方法签名完全错误:JNINativeMethod数组中的签名与Java方法的实际签名不匹配,同时Native函数的参数、返回值和Java层定义不对应。
  3. C++函数名 mangling 问题:C++编译会自动修改函数名,未用extern "C"包裹JNI函数,可能导致动态注册时找不到正确的函数地址。
  4. JNI_OnLoad代码错误:GetEnv参数传递错误、FindClass拼写错误。
  5. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:25:37