'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);
为什么我无法访问我的数据 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);