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!");

}

}

[4112 byte] By [gregstef] at [2007-9-26 2:58:25]
# 1

Let's see... you create the object.

ret_data = (*env)->NewObject(env, data_class, data_constructor);

Then you loose that reference for another. Not sure if that is a good idea, but maybe it is.

ret_data = (jobject)

(*env)->NewGlobalRef(env, ret_data);

Then you overwrite that data, with a structure that you made up on your own, with something that has nothing to do with java.

memcpy(ret_data, &test_data,

sizeof (Test_data));

And then when java tries to look at that, because it figures it has something to do with java, which it doesn't, it blows up.

I would say your program is working exactly the way you programmed it to.

So what is the problem?

jschell at 2007-6-29 10:53:21 > top of Java-index,Core,Core APIs...