【问题标题】:Android: Passing float values from Java to JNI is always NaNAndroid:将浮点值从 Java 传递到 JNI 始终是 NaN
【发布时间】:2016-05-04 02:46:17
【问题描述】:

短版:我可以使用 JNI jdouble 将双精度值从 Java 传递到 C++。但是,当我使用浮点数时,C++ jfloat 参数始终为 NaN。

加长版: 我正在为 VS 2015 修改 hello-gl2 Android 示例,该示例绘制了一个三角形 (https://code.msdn.microsoft.com/hello-gl2-android-3b61896c),添加了一个简单的函数来旋转三角形。

在 gl_code.cpp 中:

extern "C" {
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_updateAngle(JNIEnv * env, jfloat dAngle);
};
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_updateAngle(JNIEnv * env, jfloat dAngle)
{
    __android_log_print(ANDROID_LOG_DEBUG, "DEBUG", "updateAngle: %f", dAngle);
    rotationAngle += dAngle;
}

在 GL2JNILib.java 中:

public class GL2JNILib {
    public static native void updateAngle(float dAngle);
}

这都是从 GL2JNIView.java 调用的:

GL2JNILib.updateAngle(0.5f);

无论我从 Java 传递什么值,VS 调试器都会显示 jfloat dAngle 的值为 nan(3b52bc),logcat 显示“nan”,而 OpenGL 通过不绘制任何内容来确认这一点。

我在 Nexus 9 硬件设备上运行。使用 Nexus_5_API_22_x86 模拟器时,我似乎得到了许多不同的值,有时是 NaN,即使我总是传入 0.5f。如果我在上面的所有代码中将“jfloat”替换为“jdouble”,将“float”替换为“double”,则设备和模拟器上的一切正常。

我做错了什么?谢谢!!

【问题讨论】:

    标签: android android-ndk java-native-interface nan


    【解决方案1】:

    您在本机方法中缺少第二个参数:jclass。您在 C 中的方法签名应该是:

    JNIEXPORT void JNICALL
        Java_com_android_gl2jni_GL2JNILib_updateAngle(JNIEnv *env,
                                                      jclass classz,
                                                      jfloat dAngle);
    

    第二个参数是jclass,因为你的方法是static。如果它是类的实例方法,那么第二个参数将是 jobject(对象的 this。)您可以考虑使用“javah”工具来帮助您生成方法签名。

    【讨论】:

    • 非常感谢!我不知道为什么它适用于双打,但我确实错过了第二个参数,现在一切都很好。
    • 它适用于双精度数,因为 64 位参数在堆栈上必须是 64 位对齐的。 classz 参数获得了 32 位填充。
    猜你喜欢
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    相关资源
    最近更新 更多