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

Java JNI调用C语言计算BMI输出NaN该如何修复

问题根因

NaN输出的核心问题出在C代码的字段读取逻辑错误:

  • Java代码中weight和height的声明类型是double,你在C代码中已经通过GetDoubleField正确读取到了两个字段的值,却又额外调用了GetIntField再次读取同一字段。GetIntField会把存储double类型的内存空间按int格式强制解析,得到的是完全错误的垃圾值,绝大多数情况下会得到height1 = 0,后续计算weight1 / (0 * 0)就会产生NaN。

修复方案

直接删除C代码中两行错误的GetIntField调用即可,修复后的C代码如下:

#include <jni.h>
#include <math.h>

JNIEXPORT jdouble JNICALL Java_BMICalculator_BMIcalculate(JNIEnv *env, jobject obj){
    jdouble total, weight1, height1 ;
    jfieldID fid1, fid2;
        
    jclass cls = (*env)->GetObjectClass(env,obj);
    fid1 = (*env)->GetFieldID(env,cls,"weight","D");
    fid2 = (*env)->GetFieldID(env,cls,"height","D");
    
    if((fid1 == NULL) || (fid2 == NULL)) return 0;
    
    weight1 = (*env)->GetDoubleField(env,obj,fid1);
    height1 = (*env)->GetDoubleField(env,obj,fid2);
    // 已删除错误的GetIntField调用
    height1 = height1 / 100;
    
    total = weight1 / ( height1 * height1 );    
    return total;
}

额外注意事项

  • 编译动态库时要保证链接了JDK的jni头文件路径,比如Linux下编译命令参考:gcc -shared -fPIC -I$JAVA_HOME/include -I$JAVA_HOME/include/linux Calculate.c -o libCalculate.so
  • 运行Java代码时要添加JVM参数指定动态库路径:java -Djava.library.path=. BMICalculator
  • 动态库命名要符合平台规则:Windows下为Calculate.dll,Linux下为libCalculate.so,MacOS下为libCalculate.jnilib

内容的提问来源于stack exchange,提问作者TAI YU ZHE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:15:03