Joo*_*kka 32 java-native-interface
JNI教程,例如本教程,很好地介绍了如何访问对象中的原始字段,以及如何访问作为显式函数参数提供的数组(即作为子类jarray).但是如何访问作为字段内的字段的Java(原始)数组jobject?例如,我想操作以下Java对象的字节数组:
class JavaClass {
...
int i;
byte[] a;
}
Run Code Online (Sandbox Code Playgroud)
主程序可能是这样的:
class Test {
public static void main(String[] args) {
JavaClass jc = new JavaClass();
jc.a = new byte[100];
...
process(jc);
}
public static native void process(JavaClass jc);
}
Run Code Online (Sandbox Code Playgroud)
相应的C++方面将是:
JNIEXPORT void JNICALL Java_Test_process(JNIEnv * env, jclass c, jobject jc) {
jclass jcClass = env->GetObjectClass(jc);
jfieldID iId = env->GetFieldID(jcClass, "i", "I");
// This way we can get and set the "i" field. Let's double it:
jint i = env->GetIntField(jc, iId);
env->SetIntField(jc, iId, i * 2);
// The jfieldID of the "a" field (byte array) can be got like this:
jfieldID aId = env->GetFieldID(jcClass, "a", "[B");
// But how do we operate on the array???
}
Run Code Online (Sandbox Code Playgroud)
我正在考虑使用GetByteArrayElements它,但它想要一个ArrayType作为它的论点.显然我错过了一些东西.有办法吗?
Daf*_*aff 39
我希望这会对你有所帮助(也可以查看JNI Struct参考文献):
// Get the class
jclass mvclass = env->GetObjectClass( *cls );
// Get method ID for method getSomeDoubleArray that returns a double array
jmethodID mid = env->GetMethodID( mvclass, "getSomeDoubleArray", "()[D");
// Call the method, returns JObject (because Array is instance of Object)
jobject mvdata = env->CallObjectMethod( *base, mid);
// Cast it to a jdoublearray
jdoubleArray * arr = reinterpret_cast<jdoubleArray*>(&mvdata)
// Get the elements (you probably have to fetch the length of the array as well
double * data = env->GetDoubleArrayElements(*arr, NULL);
// Don't forget to release it
env->ReleaseDoubleArrayElements(*arr, data, 0);
Run Code Online (Sandbox Code Playgroud)
好的,我使用方法而不是字段(我考虑调用Java getter清理器),但您可能也可以为字段重写它.不要忘记发布,并在评论中你可能仍需要获得长度.
编辑:重写您的示例以获取字段.基本上用GetObjectField替换CallObjectMethod.
JNIEXPORT void JNICALL Java_Test_process(JNIEnv * env, jclass c, jobject jc) {
jclass jcClass = env->GetObjectClass(jc);
jfieldID iId = env->GetFieldID(jcClass, "i", "I");
// This way we can get and set the "i" field. Let's double it:
jint i = env->GetIntField(jc, iId);
env->SetIntField(jc, iId, i * 2);
// The jfieldID of the "a" field (byte array) can be got like this:
jfieldID aId = env->GetFieldID(jcClass, "a", "[B");
// Get the object field, returns JObject (because Array is instance of Object)
jobject mvdata = env->GetObjectField (jc, aID);
// Cast it to a jdoublearray
jdoubleArray * arr = reinterpret_cast<jdoubleArray*>(&mvdata)
// Get the elements (you probably have to fetch the length of the array as well
double * data = env->GetDoubleArrayElements(*arr, NULL);
// Don't forget to release it
env->ReleaseDoubleArrayElements(*arr, data, 0);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在 gcc 6.3 中,我从这样的一行中收到一条警告,说“取消引用类型双关指针将破坏严格别名规则”:
jdoubleArray arr = *reinterpret_cast<jdoubleArray*>(&mvdata);
Run Code Online (Sandbox Code Playgroud)
但是由于 jdoubleArray 本身是一个指向类 _jdoubleArray 的指针,所以在转换之前不需要获取地址,并且这个 static_cast 可以在没有警告的情况下工作:
jdoubleArray arr = static_cast<jdoubleArray>(mvdata);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35115 次 |
| 最近记录: |