JNI memory control: DLL -> Java reference passing
I'm having great difficulty trying to pass data structure
ptr's as object ref's through (*env)->CallVoidMethod():
I believe the memory is getting released by the DLL by the time the Java method executes, or I'm just lost
beyond words. Here's the src. Java && C sides...
TestData is just an aggregate class that has the cited fields.
HELP!!
JAVA
package joic;
import java.*;
import java.io.*;
import java.lang.*;
public class BufferIf
{
static
{ // Only do this once
System.loadLibrary("native_parser");
CmdParse.dll_Init("orla6670");
}
public static native void initiateDataTransfer(
Object call_obj,
String callback_method,
String method_signature);
public void passDataFromC(Object data)
{
TestData obj_ref;
if (data == null)
{
System.out.println("Null data!");
}
else
{
System.out.println("I make it this far.");
obj_ref = (TestData) data; // Dies
System.out.println("DATA FROM C as String:" +
obj_ref.toString());
System.out.println("DATA as obj:" +
obj_ref.test_int +
obj_ref.test_float +
obj_ref.test_double);
}
}
public BufferIf()
{
super();
}
public static void main(String args[])
{ // I'm running this
String params;
BufferIf obj = new BufferIf();
try
{
params = "(Ljava/lang/Object;)V";
obj.initiateDataTransfer(obj,
"passDataFromC",
params);
}
catch (NoSuchMethodException e)
{
System.out.println("NoSuchMethodException!");
}
}
}
-- C dll
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include "./joic_BufferIf.h"
#include "./oic_defs.h"
#include "./oic_type.h"
typedef struct
{
inttest_int;
float test_float;
double test_double;
// chartest_string[16];
} Test_data;
static Test_data test_data;
jobject ret_data;
charbuffer[128];
JNIEXPORT void JNICALL Java_joic_BufferIf_initiateDataTransfer(
JNIEnv *env,jclasscls,
jobjectcall_obj_ref,
jstringcallback_name,
jstringsignature)
{
jmethodID callback_id;
jmethodID data_constructor;
jclasscalling_class;
jclassdata_class;
const char *callback_method;
const char *method_sig;
char *args[1];
callback_method =
(*env)->GetStringUTFChars(env, callback_name, 0);
method_sig=
(*env)->GetStringUTFChars(env, signature, 0);
calling_class=
(*env)->FindClass(env, "joic.BufferIf");
callback_id =
(*env)->GetMethodID(env, calling_class,
callback_method, method_sig);
(*env)->ReleaseStringUTFChars(env, callback_name,
callback_method);
(*env)->ReleaseStringUTFChars(env,
signature,
method_sig);
if (callback_id)
{
test_data.test_int= 80599;
test_data.test_float = 8.0599f;
test_data.test_double = 8.05999999999;
args[0] = buffer;
memcpy(buffer, &test_data, sizeof(Test_data));
data_class =
(*env)->FindClass(env, "joic.TestData");
data_constructor =
(*env)->GetMethodID(env, data_class,
"<init>", "()V");
if (data_class && data_constructor)
{
// Constructs obj in memory controlled by JRE?
ret_data =
(*env)->NewObject(env, data_class,
data_constructor);
ret_data = (jobject)
(*env)->NewGlobalRef(env, ret_data);
if (ret_data)
{
memcpy(ret_data, &test_data,
sizeof (Test_data));
(*env)->CallVoidMethod(env, call_obj_ref,
callback_id, ret_data);
}
}
}
else
{
printf("Couldn't get method!");
}
}

