Подтвердить что ты не робот

Передача типов данных с Java на C (или наоборот) с использованием JNI

Используя JNI, мы можем передавать пользовательские типы данных с Java на C (или наоборот)? Я вижу сопоставление примитивных типов данных с типами в C, однако не слишком уверенным, можем ли мы отправлять через наши собственные типы данных (например, Отправить или вернуть объект Employee или что-то еще!).

4b9b3361

Ответ 1

Если вы собираетесь делать это с большим количеством объектов, лучше всего что-то вроде Swig. Вы можете использовать тип задания для передачи пользовательских объектов. Синтаксис не очень приятный, возможно, есть лучший способ написать это.

Пример объекта Employee:

public class Employee {
    private int age;

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

    public int getAge() {
        return age;
    }
}

Вызвать этот код у какого-либо клиента:

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);
}

Вы могли бы использовать JNI-функции для передачи объекта-сотрудника из Java в C в качестве аргумента метода задания:

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;
}

Передача объекта сотрудника обратно из C в Java в качестве задания, вы можете использовать:

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;
}