'foo_model' 引用的 JVM 对象属于 'Class<Foo>' 类型,它无权访问 'Foo' 中声明的字段 'float a'

JVM object referenced by 'foo_model' is of type 'Class<Foo>' and it does not have access to field 'float a' declared in 'Foo'

为什么我无法访问我的数据 class 上的 public 成员?

在我的测试中 Android Kotlin/NDK 应用程序,GetFloatField 正在报告

JVM object referenced by 'foo_model' is of type 'Class' and it does not have access to field 'float a' declared in 'Foo'.

Class<Foo>是一个数据class我用所有public成员定义的。

我是 Kotlin 的新手,所以这个应用程序只是一个练习,让我学习如何将自定义结构传入和传出原生层。

MainActivity.kt

package com.example.structtest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

public data class Foo(var a: Float = 3.14f, var b: Int = 10)

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var f = Foo(3.14f, 10)

        var dFoo = doubleFoo(f)
        sample_text.text = "foo.a = ${dFoo.a}, foo.b=${dFoo.b}"
    }

    external fun doubleFoo(_foo : Foo): Foo

    companion object {
        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("native-lib")
        }
    }
}

native-lib.cpp:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_structtest_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

extern "C" JNIEXPORT jobject JNICALL
Java_com_example_structtest_MainActivity_doubleFoo(
        JNIEnv* env,
        jobject /* this */,
        jobject _foo) {

    auto foo_model = env->GetObjectClass(_foo);
    auto const foo_float_field = env->GetFieldID(foo_model, "a", "F");
    auto const foo_int_field   = env->GetFieldID(foo_model, "b", "I");

    //
    // This is where I get the error, on these GetFloatField calls
    //
    auto const foo_float = env->GetFloatField(foo_model, foo_float_field);
    auto const foo_int = env->GetFloatField(foo_model, foo_int_field);

    // I'm not even sure if these lines do anything.
    // I suspect the error being thrown above crashes the app before these are executed
    auto new_foo_model  = env->FindClass("com/example/structtest/Foo");
    auto constructor = env->GetMethodID(new_foo_model, "<init>", "(FI)V");
    auto new_foo = env->NewObject(new_foo_model, constructor);

    return new_foo;
}

您正在尝试从 Class 对象 describing Foo 中读取字段 a(代码中的 foo_model ) 而不是直接来自 Foo 实例(代码中的 _foo)。

env->GetFloatField(foo_model, foo_float_field);改为

env->GetFloatField(_foo, foo_float_field);