我在C ++中有一个函数:
std::vector<std::vector<float>> const &GetVertices() { return m_Vertices; }
我需要通过JNI将此值返回给Java。
因此,由于我需要返回vector
中的vector
,因此我认为必须使用jobjectArray
,如下所示:
extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_google_ar_core_examples_
java_helloar_HelloArActivity_fillListWithData(
JNIEnv *env,
jobject /* this */
)
在Java中,我有以下方法:
public native Object[] fillListWithData();
所以,我的问题是,如何将vector<vector<float>>
转换为jobjectArray
?
我知道有一种方法可以创建jobjectArray
:
jobjectArray verticesArr = env->NewObjectArray(verticesVec.size(), WHAT CLASS SHOULD BE HERE?,NULL);
那我该如何输入值?
完整的类实现
extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_google_ar_core_examples_java_
helloar_HelloArActivity_fillListWithData(
JNIEnv *env,
jobject /* this */
) {
//verticesVec
vector<vector<float>> verticesVec = initializer->GetVertices(); // THIS VECTOR I NEED TO CONVERT TO JOBJECTARRAY
jobjectArray verticesArr = env->NewObjectArray(verticesVec.size(), WHAT CLASS SHOULD BE HERE?,NULL);
//HOW TO FILL THE ARRAY HERE??
return verticesArr;
}
答案 0 :(得分:0)
取决于您要如何对Java中的数据进行操作,例如添加更多元素?您没有提到这一点,所以答案无法更具体。但也许您想要float的“ java / util / ArrayList”。
以下答案应为您指明正确的方向: return a jobjectArray which contains lists of data。
对于其他类型的列表,代码看起来类似。少量的网络搜索将提供几种解决方案。
如果速度(CPU /延迟)和数据量并不重要,那么我建议您将数据序列化为JSON并以字符串形式返回,而不是对Java数据结构进行所有混乱的处理。使用例如JsonCpp可以很容易地将包括对象的C ++数据类型序列化为JSON,并且在Java方面,有多个用于反序列化的包(再次是Web搜索),并且许多Java框架都为此提供了内置工具。
答案 1 :(得分:0)
您必须玩java.util.Vector
。这样,您可以对...进行非常简单的映射
(C++ side) vector<vector<float> > ---> Vector<Vector<Float>> (Java side)
代码本身将很难看。请记住,由于深奥的语法,与JNI玩起来并不是一种令人愉快的经历。
无论如何,您要做的是在C++
端创建所有内容并将其传递回Java
。
只是摘录
vector<vector<float> > vect {
{ 1.1, 1.2, 1.3 },
{ 2.1, 2.2, 2.3 },
{ 3.1, 3.2, 3.3 }
};
...
...
jclass vectorClass = env->FindClass("java/util/Vector");
...
jclass floatClass = env->FindClass("java/lang/Float");
...
jmethodID mid = env->GetMethodID(vectorClass, "<init>", "()V");
jmethodID addMethodID = env->GetMethodID(vectorClass, "add", "(Ljava/lang/Object;)Z");
// Outer vector
jobject outerVector = env->NewObject(vectorClass, mid);
...
for(vector<float> i : vect) {
// Inner vector
jobject innerVector = env->NewObject(vectorClass, mid);
for(float f : i) {
jmethodID floatConstructorID = env->GetMethodID(floatClass, "<init>", "(F)V");
...
// Now, we have object created by Float(f)
jobject floatValue = env->NewObject(floatClass, floatConstructorID, f);
...
env->CallBooleanMethod(innerVector, addMethodID, floatValue);
}
env->CallBooleanMethod(outerVector, addMethodID, innerVector);
}
env->DeleteLocalRef(vectorClass);
env->DeleteLocalRef(floatClass);
您可以在此处找到完整的示例代码:
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo045
运行测试后,您可以看到基于C++
的数据已传递给Java
> make test
/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java -Djava.library.path=:./lib -cp target recipeNo045.VectorOfVectors
library: :./lib
[1.1,1.2,1.3]
[2.1,2.2,2.3]
[3.1,3.2,3.3]