[英]How to pass List from Java to JNI C++ as vector by ref?
I am fresh in C++ and JNI我刚接触 C++ 和 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.从 Java 中,我将一个空
List
传递给 JNI,JNI 从MyClass
调用方法loadData(std::vector<int>)
并且此方法用数据填充我的列表。
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这是我用纯 C++ 编写的方法,现在我需要像这样从 Java 中使用它
public native void fillListWithData(List<Integer> list);
So, I wrote such method in JNI to associate them所以,我在JNI中写了这样的方法来关联它们
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++...我无法理解如何通过 JNI 引用将此列表传递给 C++...
Any ideas appreciate任何想法赞赏
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您所要做的就是将
List
传递给您的本机代码并使用基于JNI
的访问方法将其填充到JNI
部分中
#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.请注意,您不必在
JNI
创建List
对象,因为您已经在那里 - 在C++
代码中创建了它。 It is passed as argument of native
method.它作为
native
方法的参数传递。
You can find full sample code here:您可以在此处找到完整的示例代码:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo046 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.运行代码后,您可以看到来自
C++
数据通过List
对象传递。
> 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
The answer mentioned by @Oo.oO may seem to work in Windows 10, But is not in the case with Windows 8. @Oo.oO 提到的答案似乎适用于 Windows 10,但不适用于 Windows 8。
Windows 8 does'nt support any containers from Cpp Libraries to work with. Windows 8 不支持使用 Cpp 库中的任何容器。
The Reported Error would be - " %1 is not a valid Win32 Application "报告的错误将是 - “%1 不是有效的 Win32 应用程序”
This occurs while running the Java Program.这发生在运行 Java 程序时。
The dll file generated here seem to be the issue.此处生成的 dll 文件似乎是问题所在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.