| Author |
Return a Structure Object from C to Java Through JNI
|
Ajay Singh
Ranch Hand
Joined: Jan 04, 2008
Posts: 105
|
|
HI all i am using the JNI to return an integer array object from a C class function to the java code.Now i want to return a structure object containing the student's record (name,age etc) to the java code.can anyone tell me what changes to be made to the following c file #include <jni.h> #include "Hello.h" #include <stdio.h> struct student { char *name; int age; }student1; student1.name="Jack"; student1.age=23; JNIEXPORT jobject JNICALL Java_Hello_sayHello(JNIEnv *env, jobject obj, jintArray arr) { return arr; } My java file is as under:- public class Hello { static { System.loadLibrary("hello"); } public native Object sayHello(int [] arr); public static void main(String[] args) { Hello p = new Hello(); int arr[] = new int[10]; for (int i = 0; i < 10; i++) { arr[i] = i; } int [] len = (int[]) p.sayHello(arr); System.out.println("sum = " + len.length); //length of the array } } Any help would be appriciated
|
 |
Rob Spoor
Saloon Keeper
Joined: Oct 27, 2005
Posts: 17250
|
|
First of all, you will need to create a class similar to the structure in Java - with a String and int field. Now you have two options: 1) create the object in Java and pass it to the native method. This then sets the fields. 2) create the object in the native method. Check JNI 1.1 Specification, especially JNI Functions. Here's a little code to show how an object can be created using JNI: <blockquote>code: <pre name="code" class="core">jclass cls; jmethodID constructor; jvalue args[2]; jobject object; // get a reference to your class if you don't have it already cls = (*env)->FindClass(env, "mypackage/Student"); // get a reference to the constructor; the name is <init> constructor = (*env)->GetMethodID(env, cls, "<init>", "(ILjava/lang/String;)V"); // set up the arguments; i means int, l means object args[0].i = 23; args[1].l = (*env)->NewStringUTF(env, "Jack"); object = (*env)->NewObjectA(env, cls, constructor, args);</pre> </blockquote> <blockquote>code: <pre name="code" class="core">package mypackage; public class Student { private int age; private String name; public Student(int age, String name) { this.age = age; this.name = name; } // the rest of the class }</pre> </blockquote> [ July 17, 2008: Message edited by: Rob Prime ]
|
SCJP 1.4 - SCJP 6 - SCWCD 5
How To Ask Questions How To Answer Questions
|
 |
Ajay Singh
Ranch Hand
Joined: Jan 04, 2008
Posts: 105
|
|
HI Rob Thanks for your reply Accordingly i modified the files Hello.java****************** public class Hello { static { System.loadLibrary("hello"); } public static native Student sayHello(); public static void main(String[] args) { Hello p = new Hello(); Student len = p.sayHello(); System.out.println("Name = " + len.name); System.out.println("Age = " + len.age); } public class Student { private int age; private String name; public Student(int age, String name) { this.age = age; this.name = name; } // the rest of the class } } and Hello.c #include <jni.h> #include "Hello.h" #include <stdio.h> struct student { char *name; int age; }student1; JNIEXPORT jobject JNICALL Java_Hello_sayHello(JNIEnv *env, jclass cls) { jmethodID constructor; jvalue args[2]; jobject object; cls = (*env)->FindClass(env, "Student"); constructor = (*env)->GetMethodID(env, cls, "<init>", "(ILjava/lang/String V"); args[0].i = 23; args[1].l = (*env)->NewStringUTF(env, "Jack"); object = (*env)->NewObjectA(env, cls, constructor, args); return object; } Hello.h contains JNIEXPORT jobject JNICALL Java_Hello_sayHello (JNIEnv *, jclass); Now when i run the application using java hello My JVM Crashes getting the following error messages "An Unexpected Error has been detected by Hotspot Virtual Machine............" I dont know where i am doing wrong.please help
|
 |
Rob Spoor
Saloon Keeper
Joined: Oct 27, 2005
Posts: 17250
|
|
The full classname is not Student - it is Hello$Student (since it's an inner class). Because of this, FindClass will not find the class and return NULL. It also throws a ClassNotFoundException, but the problem with native code is - it doesn't return immediately after throwing an exception but only after the current function has finished. Your error is thrown earlier because of a native "NullPointerException". Now I've changed the class name, and it can't find the constructor now. If I make the class static it works. Now I've also tried to make the class non-static and the creation method as well - because you can't create an instance of a non-static inner class inside a static context of course. This didn't solve the issue though. Therefore, I am sorry to say that I do not know how to create an instance of a non-static inner class in JNI.
|
 |
 |
|
|
subject: Return a Structure Object from C to Java Through JNI
|
|
|