ฉันพยายามใช้ Android NDK
มีวิธีคืนอาร์เรย์ (ในกรณีของฉันint[]
) สร้างใน JNI ถึง Java หรือไม่ ถ้าเป็นเช่นนั้นโปรดให้ตัวอย่างรวดเร็วของฟังก์ชั่น JNI ที่จะทำเช่นนี้
ขอบคุณ
ฉันพยายามใช้ Android NDK
มีวิธีคืนอาร์เรย์ (ในกรณีของฉันint[]
) สร้างใน JNI ถึง Java หรือไม่ ถ้าเป็นเช่นนั้นโปรดให้ตัวอย่างรวดเร็วของฟังก์ชั่น JNI ที่จะทำเช่นนี้
ขอบคุณ
คำตอบ:
หากคุณตรวจสอบเอกสารและยังมีคำถามที่ควรเป็นส่วนหนึ่งของคำถามเริ่มต้นของคุณ ในกรณีนี้ฟังก์ชัน JNI ในตัวอย่างจะสร้างอาร์เรย์จำนวนหนึ่ง อาร์เรย์นอกประกอบด้วย 'วัตถุ' NewObjectArray()
อาร์เรย์สร้างด้วยฟังก์ชั่ จากมุมมองของ JNI นั่นคืออาเรย์สองมิติคือออบเจ็กต์ที่มีอาเรย์ภายในจำนวนหนึ่ง
ต่อไปนี้สำหรับวงสร้างอาร์เรย์ด้านในซึ่งเป็นชนิด int [] NewIntArray()
โดยใช้ฟังก์ชั่น หากคุณเพียงแค่ต้องการส่งกลับ ints อาเรย์แบบมิติเดียวNewIntArray()
ฟังก์ชันจะเป็นสิ่งที่คุณใช้เพื่อสร้างค่าส่งคืน หากคุณต้องการสร้างอาเรย์แบบมิติเดียวของ Strings คุณจะต้องใช้NewObjectArray()
ฟังก์ชั่น แต่มีพารามิเตอร์ต่างกันสำหรับคลาส
เนื่องจากคุณต้องการคืนค่า int array ดังนั้นโค้ดของคุณจะมีลักษณะดังนี้:
JNIEXPORT jintArray JNICALL Java_ArrayTest_initIntArray(JNIEnv *env, jclass cls, int size)
{
jintArray result;
result = (*env)->NewIntArray(env, size);
if (result == NULL) {
return NULL; /* out of memory error thrown */
}
int i;
// fill a temp structure to use to populate the java int array
jint fill[size];
for (i = 0; i < size; i++) {
fill[i] = 0; // put whatever logic you want to populate the values here.
}
// move from the temp structure to the java structure
(*env)->SetIntArrayRegion(env, result, 0, size, fill);
return result;
}
หากมีคนต้องการทราบวิธีการคืนค่า String [] array:
รหัสจาวา
private native String[] data();
การส่งออกพื้นเมือง
JNIEXPORT jobjectArray JNICALL Java_example_data() (JNIEnv *, jobject);
รหัสเนทีฟ
JNIEXPORT jobjectArray JNICALL
Java_example_data
(JNIEnv *env, jobject jobj){
jobjectArray ret;
int i;
char *message[5]= {"first",
"second",
"third",
"fourth",
"fifth"};
ret= (jobjectArray)env->NewObjectArray(5,
env->FindClass("java/lang/String"),
env->NewStringUTF(""));
for(i=0;i<5;i++) {
env->SetObjectArrayElement(
ret,i,env->NewStringUTF(message[i]));
}
return(ret);
}
จากลิงค์: http://www.coderanch.com/t/326467/java/java/Returning-String-array-program-Java
จากคำถามที่ถามไปแล้วสิ่งนี้จะถูกอธิบายในคำตอบแรกว่าเราจะผ่าน int [] ผ่าน jobjectArray ได้อย่างไร แต่นี่คือตัวอย่างวิธีที่เราสามารถส่งคืน jobjectArray ซึ่งมีรายการข้อมูล สิ่งนี้มีประโยชน์สำหรับสถานการณ์เช่น: เมื่อมีคนต้องการส่งคืนข้อมูลในรูปแบบ 2D เพื่อวาดเส้นที่มีจุด x และ y ตัวอย่างด้านล่างแสดงวิธีที่ jobjectArray สามารถส่งคืนข้อมูลในรูปแบบของรูปแบบต่อไปนี้:
อินพุต Java ไปยัง JNI:
Array [ Arraylist
of x float points] [ Arraylist
ของ y float points]
JNI เอาต์พุตไปยัง java:
jobjectArray
[ Arraylist
ของ x คะแนนชี้] [ Arraylist
จากคะแนนลอย y]
extern "C" JNIEXPORT jobjectArray JNICALL
_MainActivity_callOpenCVFn(
JNIEnv *env, jobject /* this */,
jobjectArray list) {
//Finding arrayList class and float class(2 lists , one x and another is y)
static jclass arrayListCls = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));
jclass floatCls = env->FindClass("java/lang/Float");
//env initialization of list object and float
static jmethodID listConstructor = env->GetMethodID(arrayListCls, "<init>", "(I)V");
jmethodID alGetId = env->GetMethodID(arrayListCls, "get", "(I)Ljava/lang/Object;");
jmethodID alSizeId = env->GetMethodID(arrayListCls, "size", "()I");
static jmethodID addElementToList = env->GetMethodID(arrayListCls, "add", "(Ljava/lang/Object;)Z");
jmethodID floatConstructor = env->GetMethodID( floatCls, "<init>", "(F)V");
jmethodID floatId = env->GetMethodID(floatCls,"floatValue", "()F");
//null check(if null then return)
if (arrayListCls == nullptr || floatCls == nullptr) {
return 0;
}
// Get the value of each Float list object in the array
jsize length = env->GetArrayLength(list);
//If empty
if (length < 1) {
env->DeleteLocalRef(arrayListCls);
env->DeleteLocalRef(floatCls);
return 0;
}
// Creating an output jObjectArray
jobjectArray outJNIArray = env->NewObjectArray(length, arrayListCls, 0);
//taking list of X and Y points object at the time of return
jobject xPoint,yPoint,xReturnObject,yReturnObject;
//getting the xList,yList object from the array
jobject xObjFloatList = env->GetObjectArrayElement(list, 0);
jobject yObjFloatList = env->GetObjectArrayElement(list, 1);
// number of elements present in the array object
int xPointCounts = static_cast<int>(env->CallIntMethod(xObjFloatList, alSizeId));
static jfloat xReturn, yReturn;
jobject xReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);
jobject yReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);
for (int j = 0; j < xPointCounts; j++) {
//Getting the x points from the x object list in the array
xPoint = env->CallObjectMethod(xObjFloatList, alGetId, j);
//Getting the y points from the y object list in the array
yPoint = env->CallObjectMethod(yObjFloatList, alGetId, j);
//Returning jobjectArray(Here I am returning the same x and points I am receiving from java side, just to show how to make the returning `jobjectArray`)
//float x and y values
xReturn =static_cast<jfloat >(env->CallFloatMethod(xPoint, floatId,j));
yReturn =static_cast<jfloat >(env->CallFloatMethod(yPoint, floatId,j));
xReturnObject = env->NewObject(floatCls,floatConstructor,xReturn);
yReturnObject = env->NewObject(floatCls,floatConstructor,yReturn);
env->CallBooleanMethod(xReturnArrayList,addElementToList,xReturnObject);
env->CallBooleanMethod(yReturnArrayList,addElementToList,yReturnObject);
env->SetObjectArrayElement(outJNIArray,0,xReturnArrayList);
env->SetObjectArrayElement(outJNIArray,1,yReturnArrayList);
__android_log_print(ANDROID_LOG_ERROR, "List of X and Y are saved in the array","%d", 3);
}
return outJNIArray;
วิธีง่ายๆคือเขียนข้อมูลอาร์เรย์ในไฟล์จาก C จากนั้นเข้าถึงไฟล์จาก Java