java - 如何将类对象传递给 jni native 方法

标签 java c++ dll java-native-interface

我想创建一个 DLL,它采用 java 类对象作为参数。假设我创建了一些 native 方法,它采用 Human.class 实例作为参数。我如何编写它的 C++ 实现,以便访问人类对象?这可能吗?

(请考虑一下,我根本没有 C++ 经验。)

我已经做了一些研究,因为看起来我需要从 C++ 访问指针。这让我有点困惑,因为此时我不明白 C++ 应该如何了解人类对象及其属性。

例如

JNI.类

public class FourthJNI {

    public static native int returnAgeOfHuman(Human abc);
    public static void main(String[] args) {

        Human testHuman = new Human("ABC", 23, "M");
        /* Call to shared library */
        int ageOfHuman = FourthJNI.returnAgeOfHuman(testHuman);
        System.out.println(testHuman.toString());
        System.out.println("Age of Human: " + ageOfHuman);
    }

}

人类.类

import java.io.Serializable;

public class Human implements Serializable{


    /**
     * 
     */
    private static final long serialVersionUID = -5591105366105425395L;
    private String name;
    private int age;
    private String sex;

    public Human(String name, int age, String sex) {
        super();
        this.name = name;
        this.age = age;
        this.sex = sex;
    }


    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((sex == null) ? 0 : sex.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Human other = (Human) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (sex == null) {
            if (other.sex != null)
                return false;
        } else if (!sex.equals(other.sex))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Human [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }

}

生成的头文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class FourthJNI */

#ifndef _Included_FourthJNI
#define _Included_FourthJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     FourthJNI
 * Method:    returnAgeOfHuman
 * Signature: (LHuman;)I
 */
JNIEXPORT jint JNICALL Java_FourthJNI_returnAgeOfHuman
  (JNIEnv *, jclass, jobject);

#ifdef __cplusplus
}
#endif
#endif

我的 C++ 实现应该是什么样子?

最佳答案

您必须在 C++ 代码中解构 Java 类。您必须使用 JNI 方法并逐个字段地访问对象内部的数据。

基本上,您将不得不进行几次以下形状的调用

/* Get int field 
     Take a look here, we are passing char* with 
     field descriptor - e.g. "I" => int 
*/

jfieldID fidInt = (*env)->GetFieldID (env, cls, "iVal", "I");
jint iVal = (*env)->GetIntField (env, objarg, fidInt);
printf ("iVal: %d\n", iVal);

在这里给你完整的样本是没有意义的,把它放在这里会花费大量的空间和时间。只需按照手册操作即可。

您可以在此处找到说明:http://jnicookbook.owsiak.org/recipe-No-020/

您可以在这里找到源代码:https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo020

关于java - 如何将类对象传递给 jni native 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57524078/

相关文章:

java - timerSchedule 不服从启动定时器设置?

c++ - C 或 C++ 返回状态

c - 将无符号字符指针从matlab传递到c接口(interface)dll

.net - SQLite,将平台特定的 dll 复制到 bin 文件夹

c# - p/invoke 从 c# 调用 C dll

java - String.format() 作为常量表达式

java - 在 jsch ChannelExec 上设置环境变量

java - 使用 JFileChooser 选择网络共享

c++ - delete [] 在 Linux 中放置新对象失败

c++ - 错误说定义为公共(public)的类是私有(private)的