web-dev-qa-db-ja.com

JNIを使​​用してデータ型をJava=からC(またはその逆)に渡す

JNIを使​​用して、カスタムデータ型をJava=からCに(またはその逆に)渡すことができますか?プリミティブデータ型からCの型へのマッピングが表示されますが、独自のデータを送信できるかどうかはわかりませんタイプ(例:Employeeオブジェクトなどを送信または返す!).

31
user277460

多くのオブジェクトでこれを行う場合は、Swigのようなものが最適です。 jobjectタイプを使用して、カスタムオブジェクトを渡すことができます。構文は良くありません、おそらくこれを書くより良い方法があるでしょう。

従業員オブジェクトの例:

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

JavaからCに、jobjectメソッドの引数として従業員オブジェクトを渡すために、次のようなJNI関数を持つことができます。

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