java 通过 JNI 传递、返回和转换为列表的向量列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10813346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass, return and convert to vectors list of lists over JNI
提问by George
I need to pass from Java
我需要通过 Java
List< List<MyPoint> > points;
over jni to C++ and convert to
将 jni 转换为 C++ 并转换为
std::vector< std::vector<MyPoint> >
Process this vectors and return
处理这个向量并返回
List< List<MyPoint> >
- How correct pass and return list of lists?
- How convert list of lists of objects in vector of vectors of objects and backward?
- 如何正确传递和返回列表列表?
- 如何在对象向量向量中向后转换对象列表列表?
采纳答案by George
I solved this problem with standard tools.
我用标准工具解决了这个问题。
- Create in Java class as objects (O) container (C)
- Pass array of objects (O) from Java code to native part
- Create from array vector in C++ code
- Calculate new vectors
- Build array of containers (C) and insert into objects (O)
- Return array of containers (C)
- 在 Java 类中创建为对象 (O) 容器 (C)
- 将对象数组 (O) 从 Java 代码传递到本机部分
- 在 C++ 代码中从数组向量创建
- 计算新向量
- 构建容器数组 (C) 并插入对象 (O)
- 返回容器数组 (C)
Code implement:
代码实现:
On java part:
在java部分:
1 - Create array from list of points
1 - 从点列表创建数组
On c++ part:
在 C++ 部分:
2 - build input vector
2 - 构建输入向量
std::vector<CurvePoint> src_line;
jclass java_points_cls = env->FindClass("myPointClass");
jmethodID java_mid = env->GetMethodID(java_points_cls, "<init>", "(II)V");
jfieldID fidX = env->GetFieldID(java_points_cls, "x", "I");
jfieldID fidY = env->GetFieldID(java_points_cls, "y", "I");
int srcCount = env->GetArrayLength(srcLines);
for (int i=0; i < srcCount; i++)
{
jobject cur_pnt = env->GetObjectArrayElement(srcLines, i);
LinePoint src_point;
src_point.x = env->GetIntField(cur_pnt, fidX);
src_point.y = env->GetIntField(cur_pnt, fidY);
src_line.push_back(src_point);
}
3 - calculation lines
3 - 计算 lines
4 - build output array
4 - 构建输出数组
jclass java_line_cls = env->FindClass("myLinesClass");
jmethodID java_line_add = env->GetMethodID(java_line_cls, "addPoint", "(II)V");
jmethodID java_line_init = env->GetMethodID(java_line_cls, "<init>", "()V");
jobjectArray resLines = (jobjectArray) env->NewObjectArray(lines.size(), java_line_cls, 0);
for(int i = 0; i < lines.size(); ++i)
{
jobject cur_line = env->NewObject(java_line_cls, java_line_init);
for(int j = 0; j < lines[i].size(); ++j)
env->CallVoidMethod(cur_line, java_line_add,
lines[i][j].x,
lines[i][j].y);
env->SetObjectArrayElement(resLines, i, cur_line);
}
return resLines;
Java part
Java部分
5 - Create list of lines from returned array
5 - 从返回的数组创建行列表
回答by user2264907
JNIEXPORT jobjectArray JNICALL Java_ProcessInformation_getAllProcessPid (JNIEnv*env,jobject obj) {
vector<string>vec;
vec.push_back("Ranjan.B.M");
vec.push_back("Mithun.V");
vec.push_back("Preetham.S.N");
vec.push_back("Karthik.S.G");
cout<<vec[0];
cout<<vec[0];
jclass clazz = (env)->FindClass("java/lang/String");
jobjectArray objarray = (env)->NewObjectArray(vec.size() ,clazz ,0);
for(int i = 0; i < vec.size(); i++) {
string s = vec[i];
cout<<vec[i]<<endl;
jstring js = (env)->NewStringUTF(s.c_str());
(env)->SetObjectArrayElement(objarray , i , js);
}
return objarray;
}
回答by George
As i understand it from the reference the JNI, JNI can only work with one-dimensional arrays of primitive types or objects.
正如我从参考 JNI 中理解的那样,JNI 只能处理原始类型或对象的一维数组。
Because on the side of Java, had to translate the list into an array. Then, in the native part the array passed and the number of elements. There's going to the desired vector and processed. Returns as a result of two arrays (array with points all contours and the array with the number of points in each contour) and the number of contours. The resulting array is collected in a list of lists on the side of Java.
因为在 Java 方面,不得不将列表转换为数组。然后,在本机部分传递数组和元素数。有去所需的向量和处理。返回两个数组(包含所有轮廓点的数组和包含每个轮廓中的点数的数组)和轮廓数的结果。结果数组收集在 Java 端的列表列表中。
While the problem is not solved completely, because the JNI can not allocate memory for an existing item in the native part. Therefore it is necessary to extract the data in part, to allocate memory for them on the side of Java, and fill in the native.
虽然问题没有完全解决,因为 JNI 无法为本地部分中的现有项分配内存。因此需要将数据部分提取出来,在Java端为其分配内存,并在native填入。
A possible resolve may be the use of binders such as SWIG or JavaCpp
一个可能的解决方法可能是使用活页夹,例如 SWIG 或 JavaCpp