Open beligum opened 6 years ago
Is there a way to keep it after successful compilation?
Actually, something like mvn -Djavacpp.deleteJniFiles=false ...
This is where the vector of buffers is passed to the driver (after which the buffers sometimes already get GC):
JNIEXPORT jboolean JNICALL Java_org_bytedeco_javacpp_TISCamera_00024DeviceInterface_initialize_1buffers_1ptr(JNIEnv* env, jobject obj, jobject arg0) {
::tcam::DeviceInterface* ptr = (::tcam::DeviceInterface*)jlong_to_ptr(env->GetLongField(obj, JavaCPP_addressFID));
if (ptr == NULL) {
env->ThrowNew(JavaCPP_getClass(env, 6), "This pointer address is NULL.");
return 0;
}
jlong position = env->GetLongField(obj, JavaCPP_positionFID);
ptr += position;
::std::vector<tcam::MemoryBuffer*>* ptr0 = arg0 == NULL ? NULL : (::std::vector<tcam::MemoryBuffer*>*)jlong_to_ptr(env->GetLongField(arg0, JavaCPP_addressFID));
if (ptr0 == NULL) {
env->ThrowNew(JavaCPP_getClass(env, 6), "Pointer address of argument 0 is NULL.");
return 0;
}
jlong position0 = arg0 == NULL ? 0 : env->GetLongField(arg0, JavaCPP_positionFID);
ptr0 += position0;
jboolean rarg = 0;
jthrowable exc = NULL;
try {
bool rvalue = (bool)ptr->initialize_buffers_ptr(*ptr0);
rarg = (jboolean)rvalue;
} catch (...) {
exc = JavaCPP_handleException(env, 8);
}
if (exc != NULL) {
env->Throw(exc);
}
return rarg;
}
this is the callback function:
void JavaCPP_org_bytedeco_javacpp_TISCamera_00024sink_1callback::operator()(tcam::MemoryBuffer* arg0, void* arg1) {
jthrowable exc = NULL;
JNIEnv* env;
bool attached = JavaCPP_getEnv(&env);
if (env == NULL) {
goto end;
}
{
jvalue args[2];
jobject obj0 = NULL;
::tcam::MemoryBuffer* ptr0 = NULL;
ptr0 = (::tcam::MemoryBuffer*)arg0;
if (ptr0 != NULL) {
obj0 = JavaCPP_createPointer(env, 20);
}
if (obj0 != NULL) {
env->SetLongField(obj0, JavaCPP_addressFID, ptr_to_jlong(ptr0));
}
args[0].l = obj0;
jobject obj1 = NULL;
void* ptr1 = NULL;
ptr1 = (void*)arg1;
if (ptr1 != NULL) {
obj1 = JavaCPP_createPointer(env, 0);
}
if (obj1 != NULL) {
env->SetLongField(obj1, JavaCPP_addressFID, ptr_to_jlong(ptr1));
}
args[1].l = obj1;
if (obj == NULL) {
obj = JavaCPP_createPointer(env, 42);
obj = obj == NULL ? NULL : env->NewGlobalRef(obj);
if (obj == NULL) {
JavaCPP_log("Error creating global reference of org.bytedeco.javacpp.TISCamera.sink_callback instance for callback.");
} else {
env->SetLongField(obj, JavaCPP_addressFID, ptr_to_jlong(this));
}
ptr = &JavaCPP_org_bytedeco_javacpp_TISCamera_00024sink_1callback_allocate_callback;
}
if (mid == NULL) {
mid = JavaCPP_getMethodID(env, 42, "call", "(Lorg/bytedeco/javacpp/TISCamera$MemoryBuffer;Lorg/bytedeco/javacpp/Pointer;)V");
}
if (env->IsSameObject(obj, NULL)) {
JavaCPP_log("Function pointer object is NULL in callback for org.bytedeco.javacpp.TISCamera.sink_callback.");
} else if (mid == NULL) {
JavaCPP_log("Error getting method ID of function caller \"public native void org.bytedeco.javacpp.TISCamera$sink_callback.call(org.bytedeco.javacpp.TISCamera$MemoryBuffer,org.bytedeco.javacpp.Pointer)\" for callback.");
} else {
env->CallVoidMethodA(obj, mid, args);
if ((exc = env->ExceptionOccurred()) != NULL) {
env->ExceptionClear();
}
}
env->DeleteLocalRef(obj0);
env->DeleteLocalRef(obj1);
}
end:
if (exc != NULL) {
jstring str = (jstring)env->CallObjectMethod(exc, JavaCPP_toStringMID);
env->DeleteLocalRef(exc);
const char *msg = JavaCPP_getStringBytes(env, str);
JavaCPP_exception e(msg);
JavaCPP_releaseStringBytes(env, str, msg);
env->DeleteLocalRef(str);
JavaCPP_detach(attached);
throw e;
} else {
JavaCPP_detach(attached);
}
}
Yup, the pointer is just passed along, as an integer, and that's it.
So where does the deallocation come from then?
Like I said, if anything is happening along those lines, it's in your code in Java. But if it crashes even with an empty callback, then the problem is somewhere else.
It crashes because the created frame buffers get garbage collected... Anyway, if I keep them around in a simple java list, they are kept from GC and everything is stable, so I guess that's a good solution.
It sounds more like OpenCV or something is incorrectly freeing the memory. For example, it's probably not a good idea to change the data
field of a Mat
after it has been allocated.
I've found that the reason the data buffers get freed out of my control is that they are grouped in a (mapped) vector structure. When you just keep a reference to the vector, it's not enough to keep the GC from freeing the content of the vector. However, if you keep a parallel vector in Java, all works well. It's weird behavior, because it's counterintuitive.
Yeah, that's a bit unpolished, but I'm not sure what to do about it... In any case, usually we use a native data structure only when it's required for native calls. In your case, that doesn't sound like that's what you need, and we can just use a Java List or something so that all works as expected.
Hi,
I'm confronted with a library (the Linux API for The Imaging Source cameras) that depends on GStreamer (that in turn depends on GLib). When writing a preset for it, the API complains it can't find the GstElement class, which is part of the GStreamer framework.
What's the appropriate way to deal with these situations? Should I dig deep and create a preset for the entire GStreamer (and Glib?) API first, or do I have other options?
best,
b.