trouble handling java objects from inside java methods via C

Discussion in 'Java' started by badduck, Aug 31, 2005.

  1. badduck

    badduck Guest

    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);
    }
     
    badduck, Aug 31, 2005
    #1
    1. Advertising

  2. badduck

    Roedy Green Guest

    On 31 Aug 2005 14:05:02 -0700, "badduck" <> wrote or
    quoted :

    >public int[] i


    You really should enter a code obfuscation contest. i, j, k should be
    reserved for use as loop indexes.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Aug 31, 2005
    #2
    1. Advertising

  3. badduck

    Roedy Green Guest

    On 31 Aug 2005 14:05:02 -0700, "badduck" <> wrote or
    quoted :

    > The moment I try to use
    >int[] I always get a return value of "0" from my method calls


    What you have is a handle to a Java-style array. You can't just use
    it as if it were a C-array.

    you have to access via copy or direct access methods.

    see http://mindprod.com/jgloss/jni.html
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Aug 31, 2005
    #3
  4. badduck

    Denis Guest

    Problem is in your Java code. Replace "public void Prog() {" with
    "public Prog() {". In your original code, you define a void method
    named "Prog", instead of difnining a constructor. So, default
    constructor is used, fields "i" and "k" are not initialized. Guess what
    happens? Right, NullPointerException is thrown.

    Besides that, there is a misprint in your C code: add the second "=" to
    this line: "if (result = JNI_ERR) {".

    A pair of tips:
    1. Before calling any Java code from C, write a java main() and invoke
    your Java code from it. This way, you check that Java code is OK, and
    then you can concentrate on C=>Java invocation.

    2. Always check for exceptions after each JNI call. In your C code,
    there is only one exception check, and it happens after ten calls to
    "foolMain". This is not good. You should add check into each loop
    iteration.

    Hope this helps,
    Denis.

    -------------------
    http://www.excelsior-usa.com/jet.html
    JVM based on Ahead-of-Time compilation
     
    Denis, Sep 1, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. nobody
    Replies:
    1
    Views:
    539
    Venkatesh
    Apr 26, 2006
  2. Bret
    Replies:
    3
    Views:
    2,523
    Terry Reedy
    Jun 9, 2009
  3. horos11
    Replies:
    18
    Views:
    485
    Terry Reedy
    Oct 4, 2009
  4. Kenneth McDonald
    Replies:
    5
    Views:
    326
    Kenneth McDonald
    Sep 26, 2008
  5. ThomasW
    Replies:
    11
    Views:
    287
    ThomasW
    Sep 28, 2009
Loading...

Share This Page