B
badduck
I am trying to use the invocation API to load the JVM from C. Java
method calls from C seem to work only when the objects being manipuated
within Java are simple data-types like "int". The moment I try to use
int[] I always get a return value of "0" from my method calls.. Also,
the System.outt.printlnl() doesn't execute if I have the first
statement as "int retval = this.i[this.k++];". If I put the printtln()
before this statement, I am able to see the output of the println. It
doesn't crash the JVM but the "state" in the Java object doesn't update
either! I've even tested this code on two separate machines. What am I
doing wrong?
----My Java Code----
public class Prog {
public int[] i;
public int k;
public void Prog() {
this.i = new int[10];
for(int j=0;j<10;j++) {
this.i[j]=j;
}
this.k=0;
}
public int foolMain() {
int retval = this.i[this.k++];
System.out.println("this is a silly printtln.....");
return retval;
}
}
-----My C Code----
#include <jni.h>
#include "./Prog.h"
void main() {
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption *options;
long result;
int i,j;
jclass cls;
jmethodID mid;
jstring jstr;
jobject obj;
jclass stringClass;
jobjectArray args;
options = (void *)malloc(sizeof(JavaVMOption));
/* load the vm_arg options... */
options[0].optionString="-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (result = JNI_ERR) {
fprintf(stderr, "Can't create Java VM inside 1.2\n");
exit(1);
}
/*-------------here is where the core of the calls are handledd */
/* get the required class.. */
cls = (*env)->FindClass(env, "Prog");
if (cls == NULL) {
goto destroy;
}
printf("here-1\n");
/* get a handle to the constructor method */
mid = (*env)->GetMethodID(env, cls, "<init>","()V");
if (mid == NULL) {
goto destroy;
}
printf("here-2\n");
/* create an object of the class */
obj = (*env)->NewObject(env, cls, mid, "");
if (obj == NULL) {
goto destroy;
}
printf("here-3\n");
/* get a handle to the method */
mid = (*env)->GetMethodID(env, cls, "foolMain","()I");
if (mid == NULL) {
goto destroy;
}
printf("here-4\n");
/* call the method a bunch of times... */
for(i=0;i<10;i++) {
j = (*env)->CallIntMethod(env, obj, mid, "");
printf("j=%d\n",j);
}
printf("here-5\n");
destroy:
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
/* destroy the VM */
(*jvm)->DestroyJavaVM(jvm);
}
method calls from C seem to work only when the objects being manipuated
within Java are simple data-types like "int". The moment I try to use
int[] I always get a return value of "0" from my method calls.. Also,
the System.outt.printlnl() doesn't execute if I have the first
statement as "int retval = this.i[this.k++];". If I put the printtln()
before this statement, I am able to see the output of the println. It
doesn't crash the JVM but the "state" in the Java object doesn't update
either! I've even tested this code on two separate machines. What am I
doing wrong?
----My Java Code----
public class Prog {
public int[] i;
public int k;
public void Prog() {
this.i = new int[10];
for(int j=0;j<10;j++) {
this.i[j]=j;
}
this.k=0;
}
public int foolMain() {
int retval = this.i[this.k++];
System.out.println("this is a silly printtln.....");
return retval;
}
}
-----My C Code----
#include <jni.h>
#include "./Prog.h"
void main() {
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption *options;
long result;
int i,j;
jclass cls;
jmethodID mid;
jstring jstr;
jobject obj;
jclass stringClass;
jobjectArray args;
options = (void *)malloc(sizeof(JavaVMOption));
/* load the vm_arg options... */
options[0].optionString="-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (result = JNI_ERR) {
fprintf(stderr, "Can't create Java VM inside 1.2\n");
exit(1);
}
/*-------------here is where the core of the calls are handledd */
/* get the required class.. */
cls = (*env)->FindClass(env, "Prog");
if (cls == NULL) {
goto destroy;
}
printf("here-1\n");
/* get a handle to the constructor method */
mid = (*env)->GetMethodID(env, cls, "<init>","()V");
if (mid == NULL) {
goto destroy;
}
printf("here-2\n");
/* create an object of the class */
obj = (*env)->NewObject(env, cls, mid, "");
if (obj == NULL) {
goto destroy;
}
printf("here-3\n");
/* get a handle to the method */
mid = (*env)->GetMethodID(env, cls, "foolMain","()I");
if (mid == NULL) {
goto destroy;
}
printf("here-4\n");
/* call the method a bunch of times... */
for(i=0;i<10;i++) {
j = (*env)->CallIntMethod(env, obj, mid, "");
printf("j=%d\n",j);
}
printf("here-5\n");
destroy:
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
/* destroy the VM */
(*jvm)->DestroyJavaVM(jvm);
}