我的Java代码调用存在的C++代码来解析文件。它会生成一个保存许多数据的对象。 我将调用jni的第二种方法来访问这些数据, 当我调用第二种方法时,我必须再次解析文件。这显然是正确的行为。保持某种的C++对象在多个JNI调用活着
有没有办法来处理呢? 顺便说一句:我是新来的C++。
我的Java代码调用存在的C++代码来解析文件。它会生成一个保存许多数据的对象。 我将调用jni的第二种方法来访问这些数据, 当我调用第二种方法时,我必须再次解析文件。这显然是正确的行为。保持某种的C++对象在多个JNI调用活着
有没有办法来处理呢? 顺便说一句:我是新来的C++。
我不知道如果我理解你的问题是正确的。但我想你想要做的是保持某种C++对象在多个jni调用中存活。
你可以做很多事情。首先解析您的文件并将您的C++对象存储在全局变量中。这是最简单的解决方案,但不是一个很好的解决方案。
您还可以将你的c的生命周期++对象转换成Java。
jlong java_some_class_jni_method(...)
{
.... parse your text file ....
MyParseclass* cls = new MyParseclass(...);
....
return (jlong) cls;
}
但请记住,你需要再次删除本地C++类。所以你需要一个jni方法,并且一定要调用它。
void java_some_calls_jni_method(..., jlong clsPtr)
{
MyParseclass* cls = (MyParseclass*)clsPtr;
... do maybe do something with cls and access the data...
delete cls; // do not use the jlong again in any call
}
顺便说一句:如果你会张贴一些代码会更有帮助。但我希望这里的这个伪代码有所帮助。
太好了。这就是我要的。我会尝试。 –
我只是尝试,它的工作原理。 –
这个问题是非常相似的this one
这里是我的解决方案,以保持物体活在C++,以便从多个JNI引用它们来电:
的Java
在Java方面,我正在用long
指针创建一个类,以保持对C++对象的引用。在Java类中包装C++方法,允许我们在多个活动中使用C++方法。请注意,我正在构造函数上创建C++对象,并且正在删除清理对象。这是为了防止内存泄漏非常重要:
public class JavaClass {
// Pointer (using long to account for 64-bit OS)
private long objPtr = 0;
// Create C++ object
public JavaClass() {
createCppObject();
}
// Delete C++ object on cleanup
public void cleanup() {
deleteCppObject();
this.objPtr = 0;
}
// Native methods
public native void createCppObject();
public native void workOnCppObject();
public native void deleteCppObject();
// Load C++ shared library
static {
System.loadLibrary("CppLib");
}
}
C++
在C++的一面,我定义函数来创建,修改和删除的对象。需要提及的是,我们必须使用new
和delete
将对象存储在HEAP内存中,以便在Java类实例的整个生命周期中保持活动状态。我也存储指针CppObject
直在JavaClass
,使用getFieldId
,SetLongField
和GetLongField
:
// Get pointer field straight from `JavaClass`
jfieldID getPtrFieldId(JNIEnv * env, jobject obj)
{
static jfieldID ptrFieldId = 0;
if (!ptrFieldId)
{
jclass c = env->GetObjectClass(obj);
ptrFieldId = env->GetFieldID(c, "objPtr", "J");
env->DeleteLocalRef(c);
}
return ptrFieldId;
}
// Methods to create, modify, and delete Cpp object
extern "C" {
void Java_com_test_jnitest_JavaClass_createCppObject(JNIEnv *env, jobject obj) {
env->SetLongField(obj, getPtrFieldId(env, obj), (jlong) new CppObject);
}
void Java_com_test_jnitest_JavaClass_workOnCppObject(JNIEnv *env, jobject obj) {
CppObject* cppObj = (CppObject*) env->GetLongField(obj, getPtrFieldId(env, obj));
// Write your code to work on CppObject here
}
void Java_com_test_jnitest_JavaClass_deleteCppObject(JNIEnv *env, jobject obj) {
CppObject* cppObj = (CppObject*) env->GetLongField(obj, getPtrFieldId(env, obj));
delete cppObj;
}
}
注:
delete
。GetFieldID
,SetLongField
和GetLongField
存储从C++对象引用,但你也可以在jlong
对象的指针从Java软件商店上的其他答案的讨论。JavaObject
类作为Parcelable
,以便将我的课程用Intent
与其他课程一起传递给多个活动。
我不知道你在问什么。你问是否有方法在C++中解析文件一次?答案肯定是。也许你可以解释你试图解决这个问题的方法以及你计算的问题。 –
首先,我调用jni方法parseFile(); –
第一,我调用JNI方法parseFile()(C++代码)和一些数据返回到Java。在这之后,accoridng用户的动作,例如触摸按钮,我会调用另一个JNI方法selectNote(),在第二JNI方法的C++代码,它将使用parseFile()产生的数据,所以必须调用parseFile()再次在selectNote()(C++代码)中。 –