首页 > 解决方案 > 使用 JNI 将 float[] 从 C++ 传递到 Java

问题描述

我正在尝试将原始浮点数组从 C++“传递”(即复制)到 Java。保存源数组的 C++ 结构:

struct foo_cpp {
    float a[16];
};

保存目标数组的 Java 类:

public class foo_java {
    public float a[];

    public foo_java() {
        a = new float[16];
    }
}

尝试将数据传递给 Java 类的 C++ 函数:

extern "C" JNIEXPORT jobject JNICALL Java_com_example_myapp_Controller_process_1frame(JNIEnv *env, jclass clazz)
{
    // C++ "source array"
    foo_cpp fc;
    // Initialize fc.a here...

    // Convert from cpp to java
    jobject foo_object;
    {
        // Create the foo object
        jclass foo_class_id = env->FindClass("com/example/myapp/foo_java");
        jmethodID foo_ctor_id = env->GetMethodID(foo_class_id, "<init>", "()V");
        foo_object = env->NewObject(foo_class_id, foo_ctor_id);

        // Get the field ID
        jfieldID field_id = env->GetFieldID(foo_class_id, "a", "[F");

        // Set the fields
        {
            // Get pointer to Java object float array (Get pointer to Java class foo_java::a)
            jobject field_data = env->GetObjectField(foo_object, field_id);
            jfloatArray *fa = reinterpret_cast<jfloatArray*>(&field_data);
            float *fa_raw = env->GetFloatArrayElements(*fa, nullptr);
            for (int i = 0; i < 16; i++)
                fa_raw[i] = static_cast<float>(fc.a[i]);
        }
    }
    
    return foo_object;
}

但是,在运行此程序时,java 对象中的值与预期不符。

我错过了什么/做错了什么?

标签: javac++java-native-interface

解决方案


问题中提到的代码结果按预期工作。浮点值正确,这是误解/分层问题的典型案例。

但是,正如@Michael 在评论中指出的那样:调用 toReleaseFloatArrayElements()是防止内存泄漏所必需的。

我为此创建了一篇博文:https ://blog.insane.engineer/post/cpp_length_prefixed_strings/


推荐阅读