【问题标题】:Passing data types from Java to C (or vice versa) using JNI使用 JNI 将数据类型从 Java 传递到 C(反之亦然)
【发布时间】:2023-03-21 16:43:01
【问题描述】:

使用 JNI,我们可以将自定义数据类型从 Java 传递到 C(反之亦然)吗?我看到原始数据类型到 C 中的类型的映射,但不太确定我们是否可以发送我们自己的数据类型(例如发送或返回一个 Employee 对象或其他东西!)。

【问题讨论】:

标签: java c java-native-interface


【解决方案1】:

如果您要对很多对象执行此操作,则最好使用 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);
}

您可以使用这样的 JNI 函数将员工对象从 Java 传递到 C,作为 jobject 方法参数:

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

【讨论】:

  • 我对“LEmployee;”有疑问我尝试使用“com.pak1.Employee”和“Lcom.pak.Employee;”的部分但没有结果,有什么想法吗?
  • @Lukap:如果您的班级是 com.pak.Employee,那么班级的签名将是“Lcom/pak/Employee;”
  • @mafioso 你可以创建一个类“Ljava/lang/string;”的对象。评论完整性,怀疑你真的还需要这个......
  • jclass proc_jclass = env-&gt;FindClass(“Lcom/my/class/JavaClass”); 方法需要在您的JNI 函数的第一行调用,否则您可能会遇到ClassNotFoundExceptions。此外,这对我在类路径中的分号不起作用。一旦我从类路径字符串中删除了分号,它就起作用了。这是一个很好的答案!
  • swig 太复杂且难以使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2013-11-25
相关资源
最近更新 更多