[英]How to set multidimensional array field of Java object through JNI
在我的本机C ++代码中,有一个必须返回Java对象的函数。 使用JNI在Java代码中调用此函数。 在返回的对象内部,必须有一个二维双精度数组字段,该字段必须在返回对象之前被填充。 尽管有一些示例代码涉及在jobject内设置数组字段,但没有明确的方法来设置多维数组字段,无论它们是图元数组还是其他对象。 如何才能做到这一点?
经过研究后,我发现诀窍是将多维数组字段视为Jobject数组。 在此示例中,这些工作对象实际上是双精度数组。 可以根据需要继续进行任意尺寸的操作。 包含所涉及的多维数组字段的对象是:
package com.example;
public class ObjectTransform{
public String name;
public double[][] transform;
public ObjectTransform(){
name = "";
transform = new double[4][4];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
transform[i][j] = i == j ? 1 : 0;
}
}
其中多维数组实际上是4 x 4变换矩阵。 只是为了证明必须有一个包含数组的对象,还有另一个String字段。 有了这个,返回ObjectTransform
的本机C ++函数如下:
extern "C" JNIEXPORT jobject JNICALL Java_com_example_examplefunction(
JNIEnv* env, jclass* class_){
//Get class identifier of our object
jclass cls = env->FindClass("com/example/ObjectTransform");
//Get constructor identifier for our object
jmethodID constructor = env->GetMethodID(cls,"<init>","()V");
//Get field identifiers of our object
//Transform is a two dimensional double array, denoted as [[D
jfieldID nameID = env->GetFieldID(cls,"name","Ljava/lang/String;");
jfieldID transformID = env->GetFieldID(cls,"transform","[[D");
//Allocate object that we will return
jobject jresult = env->NewObject(cls, constructor);
//Set object name
env->SetObjectField(jresult, nameID, env->NewStringUTF("some name"));
/*
* Build object transform matrix
*/
//Get rows of the matrix in JVM heap space, we will change them
jobjectArray rows = reinterpret_cast<jobjectArray>(
env->GetObjectField(jresult,transformID));
//Allocate some temporary variables
jdoubleArray jrow;
jdouble row[4];
//Traverse rows
for(int j=0;j<4;j++){
//Traverse columns
for(int k=0;k<4;k++){
//Set current element of the matrix accordingly
row[k] = calculate_some_value(j,k);
}
//Temporarily allocate a new row in JVM heap space
//No need to unpin an array allocated with New...Array in the end
jrow = env->NewDoubleArray(4);
//Fill the newly allocated row
env->SetDoubleArrayRegion(jrow,0,4,row);
//Write the newly filled row to the appropriate row of our matrix
env->SetObjectArrayElement(rows,j,jrow);
}
return jresult;
}
可以照常从Java内部调用具有以下签名的本机函数:
package com.example;
...
private native ObjectTransform examplefunction();
从这里开始,可以直接设置任意对象的多维数组字段:代替[[D
,写[[com.example.exampleclass;
。 代替NewDoubleArray
,调用NewObjectArray
。 代替SetDoubleArrayRegion
,通过SetObjectArrayElement
分别将对象数组的所有元素设置为您事先创建的对象。
当然,欢迎对此代码进行所有改进。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.