2012-08-03 19 views
5

Soy relativamente nuevo en JNI y he aprendido los principios básicos de jugar con enteros y matrices en objetos Java usando JNI. Ahora estoy tratando de modificar/acceder a un objeto Java dentro de un objeto Java.Acceso a un objeto Java en un objeto Java en C usando JNI

He estado buscando en Internet y en Stack Overflow y todavía tengo que descubrir cómo hacerlo.

Aquí está el ejemplo.

En Java:

public class ObjectOne 
{ 
    private byte[] buff; 
    ... 
    ... 
} 

public class ObjectTwo 
{ 
    private ObjectOne obj; 
    ... 
    ... 
} 

En JNI, ¿cómo se accede "buff" de ObjectOne través ObjectTwo? Intenté algo como esto ...

JNIEXPORT void JNICALL Java_accessBuffThroughObjectTwo(JNIEnv *env, jobject obj, jobject objectTwo) 
{ 
    jclass clazz; 
    jclass bufferClazz; 
    jobject bufferJObject; 

    clazz = (*env)->GetObjectClass(env, objectTwo); 
    fid = (*env)->GetFieldID(env, clazz, "obj", "Ljava/lang/Object;"); 
    bufferJObject = (*env)->GetObjectField(env, javascsicommand, fid); 
    bufferClazz = (*env)->GetObjectClass(env, bufferJObject); <-- Fails here for Access Violation 
    fid = (*env)->GetFieldID(env, bufferClazz, "buff", "[B"); 
} 

¿Alguna ayuda sobre lo que estoy haciendo mal?

+0

El primer paso es comprobar cada llamada JNI para ver si está fallando. Segundo: ¿qué es 'javascsicommand'? –

+0

Creo que está pasando el valor incorrecto para la instancia 'obj' a [GetObjectField] (http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp16572) Ver el descriptor correcto: 'jobject GetObjectField (JNIEnv * env, jobject obj, jfieldID fieldID);' – oldrinb

+0

¿Quizás quiso pasar 'objectTwo' en lugar de' javascsicommand'? – oldrinb

Respuesta

15

Al tratar el código que puede agregar fácilmente algunas afirmaciones como esta:

JNIEXPORT void JNICALL Java_accessBuffThroughObjectTwo(JNIEnv *env, jobject obj, jobject objectTwo) { 
    jclass clazz; 
    jclass bufferClazz; 
    jobject bufferJObject; 
    jfieldID fid; 

    clazz = (*env)->GetObjectClass(env, objectTwo); 
    assert(clazz != NULL); 
    fid = (*env)->GetFieldID(env, clazz, "obj", "Ljava/lang/Object;"); 
    assert(fid != NULL); 
    bufferJObject = (*env)->GetObjectField(env, javascsicommand, fid); 
    assert(bufferJObject != NULL); 
    bufferClazz = (*env)->GetObjectClass(env, bufferJObject); 
    assert(bufferClazz != NULL); 
    fid = (*env)->GetFieldID(env, bufferClazz, "buff", "[B"); 
    assert(fid != NULL); 
} 

Si lo hace, por primera vez, verá que la primera fid será nulo. Esto se debe a que la clase ObjectTwo no tiene campos del tipo java.lang.Object. Debe cambiar la línea para tener este aspecto (pero agregar los paquetes correctos en lugar de com/package):

fid = (*env)->GetFieldID(env, clazz, "obj", "Lcom/package/ObjectOne;"); 

Si ejecuta otra vez usted encontrará que la FID ya no es nula y la afirmación pasará.

Como han sugerido otros, creo que el javascsicommand debe ser objectTwo.

Ahora el siguiente lugar donde la afirmación fallará es en bufferJObject. Esto se debe a que el campo existe pero el objeto es NULL y si revisa el código java notará que el campo obj nunca se crea una instancia y es null.

cambiar su código java a algo como esto:

public class ObjectTwo 
{ 
    private ObjectOne obj = new ObjectOne(); 
    ... 
    ... 
} 

Ahora se pasa a la afirmación e incluso pasar todas las otras afirmaciones.

En resumen estuviera accediendo null un objeto y tratando de invocar a la reflexión sobre ella:

bufferClazz = (*env)->GetObjectClass(env, bufferJObject); <-- The bufferJObject was NULL 
+0

gracias por esta respuesta detallada. Definitivamente utilizaré las afirmaciones y verificaremos NULL. Creo que se dio en el clavo cuando usted hablaba de acceder a un objeto nulo. Creo que eso es lo que me está dando la infracción de acceso – user1575243

+0

@ user1575243 Si cree que mi respuesta fue útil, marque la respuesta como aceptada! – maba

+1

@ user1575243 Si la gente como yo dedica algo de tiempo a configurar entornos de codificación, iniciar sesiones de depuración y tratar de resolver los problemas de otras personas, entonces lo menos que puede esperar de es que aceptan respuestas que les resultan útiles ... – maba

Cuestiones relacionadas