Issue
I am fresh in C++ and JNI
Flow should be like this
From Java I pass a empty List to JNI, JNI invoke method loadData(std::vector<int>) from MyClass and this method fill my list with a data.
So, question is
I have
class MyClass {
public:
MyClass();
~MyClass();
void loadData(std::vector<int> & vector);
};
void MyClass::loadData(std::vector<int> & vector)
{
const int size = 10;
vector.resize(size);
for (int i = 0; i < size; ++i) {
vector.push_back(4);
}
}
This is my method that I wrote in pure C++ and now I need to use it from Java like this
public native void fillListWithData(List<Integer> list);
So, I wrote such method in JNI to associate them
extern "C" JNIEXPORT void JNICALL
Java_com_google_ar_core_examples_java
_helloar_HelloArActivity_fillListWithData(
JNIEnv *env,
jobject /* this */,
jobject input
) {
myClass->loadData("HERE I NEED TO PASS MY " input);
}
And here how I should to invoke this method
public void TEST(){
List<Integer> list = new ArrayList<>();
fillListWithData(list);
Log.e("TAG", "HERE I NEED TO HAVE A LIST WITH FILLED DATA");
}
I can't understand how to pass this list by reference by JNI to C++...
Any ideas appreciate
Solution
In this case, it's quite simple. All you have to do is to pass List to your native code and fill it inside JNI part using JNI based access methods
#include <vector>
#include "jni.h"
#include "recipeNo046_FillTheList.h"
using namespace std;
JNIEXPORT void JNICALL Java_recipeNo046_FillTheList_fillTheList
(JNIEnv *env, jclass cls, jobject obj) {
vector<int> vect { 1, 2, 3 };
jclass listClass = env->FindClass("java/util/List");
if(listClass == NULL) {
return; // alternatively, throw exception (recipeNo019)
}
jclass integerClass = env->FindClass("java/lang/Integer");
if(integerClass == NULL) {
return; // alternatively, throw exception (recipeNo019)
}
jmethodID addMethodID = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
if(addMethodID == NULL) {
return; // - || -
}
jmethodID integerConstructorID = env->GetMethodID(integerClass, "<init>", "(I)V");
if(integerConstructorID == NULL) {
return; // - || -
}
for(int i : vect) {
// Now, we have object created by Integer(i)
jobject integerValue = env->NewObject(integerClass, integerConstructorID, i);
if(integerValue == NULL) {
return;
}
env->CallBooleanMethod(obj, addMethodID, integerValue);
}
env->DeleteLocalRef(listClass);
env->DeleteLocalRef(integerClass);
}
Note that you don't have to create List object inside JNI as you already have it there - inside C++ code. It is passed as argument of native method.
You can find full sample code here:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo046
Once you run the code, you can see data from C++ being passed through the List object.
> make test
/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java -Djava.library.path=:./lib -cp target recipeNo046.FillTheList
library: :./lib
1
2
3
Answered By - Oo.oO
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.