2010-03-23 4 views
27

En utilisant JNI pouvons-nous passer des types de données personnalisés de Java à C (ou vice versa)? Je vois un mappage de types de données primitifs à des types dans C, mais je ne sais pas trop si nous pouvons envoyer à travers nos propres types de données (par exemple, envoyer à travers ou retourner un objet employé ou quelque chose!).Passage de types de données de Java à C (ou vice versa) en utilisant JNI

+0

Vous pouvez utiliser [JNA] (https://github.com/twall/jna/) pour facilement passer des structures autour. JNA vous permet d'écrire votre liaison complètement dans le code Java. :-) –

+0

Vous pouvez. Si vous voulez faciliter la traduction Java/C, consultez [Swig] (http://www.swig.org/), qui vous permet de traduire [entre Java et les structures C/C++] (http: // www. swig.org/Doc1.3/Java.html) d'une manière simple .. –

Répondre

61

Si vous allez faire cela avec beaucoup d'objets, quelque chose comme Swig serait le meilleur. Vous pouvez utiliser le type jobject pour transmettre des objets personnalisés. La syntaxe n'est pas sympa, peut-être existe-t-il un meilleur moyen d'écrire ceci.

Exemple objet employé:

public class Employee { 
    private int age; 

    public Employee(int age) { 
     this.age = age; 
    } 

    public int getAge() { 
     return age; 
    } 
} 

Appelez ce code à partir de certains clients:

public class Client { 
    public Client() { 
     Employee emp = new Employee(32); 

     System.out.println("Pass employee to C and get age back: "+getAgeC(emp)); 

     Employee emp2 = createWithAge(23); 

     System.out.println("Get employee object from C: "+emp2.getAge()); 
    } 

    public native int getAgeC(Employee emp); 
    public native Employee createWithAge(int age); 
} 

Vous pourriez avoir des fonctions JNI comme celui-ci pour le passage d'un objet employé de Java à C, comme méthode de jobject argument:

JNIEXPORT jint JNICALL Java_Client_getAgeC(JNIEnv *env, jobject callingObject, jobject employeeObject) { 
    jclass employeeClass = (*env)->GetObjectClass(env, employeeObject); 
    jmethodID midGetAge = (*env)->GetMethodID(env, employeeClass, "getAge", "()I"); 
    int age = (*env)->CallIntMethod(env, employeeObject, midGetAge); 
    return age; 
} 

Passage d'un objet salarié de C vers Java en tant que jobje ct, vous pouvez utiliser:

JNIEXPORT jobject JNICALL Java_Client_createWithAge(JNIEnv *env, jobject callingObject, jint age) { 
    jclass employeeClass = (*env)->FindClass(env,"LEmployee;"); 
    jmethodID midConstructor = (*env)->GetMethodID(env, employeeClass, "<init>", "(I)V"); 
    jobject employeeObject = (*env)->NewObject(env, employeeClass, midConstructor, age); 
    return employeeObject; 
} 
+2

J'ai des problèmes avec "LEmployee;" partie j'ai essayé avec "com.pak1.Employee" et avec "Lcom.pak.Employee;" mais pas de résultat, des idées? – Lukap

+1

@Lukap: si votre classe est com.pak.Employee alors la signature de la classe sera "Lcom/pak/Employee;" – nautilusvn

+0

Avez-vous une idée de comment cela fonctionne pour 'String'? – mafioso

Questions connexes