2012-12-21 2 views
2

Je dois passer une structurecomment passer la structure du code C à Java avec JNI

struct Info { 
    u_int8_t timestamp[8]; 
    u_int32_t a; 
    u_int32_t b; 
    u_int32_t c; 
    ActiveInfo activeInfo[MAX_ACTIVE_SET]; 

    }; 

struct ActiveInfo 
{ 
    u_int8_t is_reference; 
    u_int16_t p; 
    u_int32_t q; 
    u_int8_t r; 
    u_int8_t s; 
    }; 
    typedef struct ActiveInfo ActiveInfo; 

Je veux passer ce (Info) Structure à mes java code.I ont goggled, mais pas obtenir des moyens complets pour faire ça.

Merci.

Répondre

4

La structure doit être définie à côté de Java, en tant que classe avec les membres. Le fait est que JNI permet à C d'accéder aux objets Java, mais pas Java pour accéder aux objets C (structs). Donc, si vous voulez "passer" quelque chose via JNI et l'avoir accessible des deux côtés, il doit s'agir d'un objet Java, puis qualifié comme jobject dans l'interface. De côté C puis, vous avez deux options:

  • soit accéder aux membres directement avec GetFieldID() et Get/Set<Type>Field, mais il est plus compliqué avec les tableaux (vous avez obtenu que je vois)
  • ou créer des méthodes Java dans cette classe pour remplir et lire de manière simplifiée, et les appeler avec Invoke<Retval>Method

Cela dépend de la conception de votre stockage de données. Vous voulez peut-être seulement un côté (C ou Java) à lire et l'autre à écrire, ce qui peut être reflété dans la conception de façon pratique.

Edit:

exemple se trouve sur le site signalé par @asgoth: www.steveolyo.com. Il y a un chapitre intitulé "Passer des structures C de Java à Java" mais ensuite il explique silencieusement comment refléter la structure C requise dans la classe Java et passer l'objet Java dans C via JNI - ce qui est exactement ce que dit ma réponse.

+0

merci pour cela, avez-vous un exemple pour le même. – Rajendra

2

Vous avez besoin d'un JNIEXPORT:

JNIEXPORT jint JNICALL 
Java_FillCStruct 
(
    JNIEnv *env, 
    jclass obj, 
    jobject info  // EntryInformation object instantiation 
) 
{ 
    testInfo entryInfo; 
    jclass clazz; 
    jfieldID fid; 
    jmethodID mid; 

    GetInfo(entryInfo); // fills in the entryInfo 

    clazz = (*env)->GetObjectClass(env, info); 
    if (0 == clazz) 
    { 
     printf("GetObjectClass returned 0\n"); 
     return(-1); 
    } 
    fid = (*env)->GetFieldID(env,clazz,"index","I"); 

    // This next line is where the power is hidden. Directly change 
    // even private fields within java objects. Nasty! 
    (*env)->SetIntField(env,info,fid,testInfo.index); 
... 

Voici un site avec quelques exemples: http://www.steveolyo.com/JNI/JNI.html

1

Vous savez déjà que le mappage ne fonctionne que d'une seule façon: vous pouvez accéder à une classe Java à partir de C/C++, mais pas vice versa. Mais il est également important de se rappeler qu'une telle cartographie implique un surcoût significatif - à la fois dans la mémoire utilisée et dans la CPU.

Par conséquent, il peut être bon de renoncer à une transparence totale. Par exemple, si vous avez seulement besoin de lire activeInfo [n] .s, vous pouvez écrire une méthode native getais (int n). Ou vous pouvez recevoir toute la structure en java en tant que DirectByteBuffer, calculer le décalage requis, et manipuler la valeur directement.

+1

merci pour cela, avez-vous un exemple de faire cela – Rajendra

Questions connexes