如何将类对象传递给 jni 本机方法
How to pass a classobject to a jni native method
我想创建一个 DLL,它将 java class 对象作为参数。假设我创建了一些本机方法,这些方法采用 Human.class 实例作为参数。为了访问人类对象,我该如何编写它的 C++ 实现?有可能吗?
(请考虑,我完全没有使用 C++ 的经验。)
我已经做了一些研究,因为看起来我需要从 C++ 访问指针。这让我有点困惑,因为此时我不明白 C++ 应该如何了解人类对象及其属性。
例如
JNI.class
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);
}
}
human.class
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
class。您必须使用 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);
在这里给你完整的样本是没有意义的,把它放在这里会花费很多 space 和时间。按照手册做就好了。
您可以在此处找到说明:http://jnicookbook.owsiak.org/recipe-No-020/
你可以在这里找到源代码:https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo020
我想创建一个 DLL,它将 java class 对象作为参数。假设我创建了一些本机方法,这些方法采用 Human.class 实例作为参数。为了访问人类对象,我该如何编写它的 C++ 实现?有可能吗?
(请考虑,我完全没有使用 C++ 的经验。)
我已经做了一些研究,因为看起来我需要从 C++ 访问指针。这让我有点困惑,因为此时我不明白 C++ 应该如何了解人类对象及其属性。
例如
JNI.class
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);
}
}
human.class
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
class。您必须使用 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);
在这里给你完整的样本是没有意义的,把它放在这里会花费很多 space 和时间。按照手册做就好了。
您可以在此处找到说明:http://jnicookbook.owsiak.org/recipe-No-020/
你可以在这里找到源代码:https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo020