我有一个与此类似的代码
struct time
{
long milliscnds;
int secs;
}
在我的java文件中,我有类似的东西
class jtime
{
long millscnds;
int secs;
}
new jtime time = new jtime();
public int native getTimeFromC(object time);
在本地课程中
getTimeFromc(JNIEnv* env, jobject thiz,jobject jtime)
{
struct time *mytime = getTime();
now to fill the jtime with mytime
}
建议吗?
答案 0 :(得分:1)
您可以简化Java类和所需的JNI代码。
目前,您的原生方法存在一些问题:
public int native getTimeFromC(object time);
Object
,但应为jtime
。jtime
对象,为什么不创建并返回jtime
对象?这个类定义有一个工厂方法来创建对象,一个构造函数可以从JNI端移动一些初始化工作。
public class jtime {
long millscnds;
int secs;
public jtime(long millscnds, int secs) {
this.millscnds = millscnds;
this.secs = secs;
}
public native static jtime FromC();
}
工厂方法可以这样实现:
JNIEXPORT jobject JNICALL Java_jtime_FromC
(JNIEnv * env, jclass clazz)
{
struct time *mytime = getTime();
jmethodID ctor = (*env)->GetMethodID(env, clazz, "<init>", "(JI)V");
jobject obj = (*env)->NewObject(env, clazz, ctor, mytime->milliscnds, mytime->secs);
return obj;
}
提示:javap
工具与javah
类似,但显示非本机方法的签名。使用javap -s jtime
,您可以看到构造函数的签名。
答案 1 :(得分:0)
如下所示:
void getTimeFromc(JNIEnv* env, jobject thiz, jobject jtime)
{
struct time *mytime = getTime();
// now to fill the jtime with mytime
jclass jtimeClazz = (*env)->GetObjectClass(jtime); // Get the class for the jtime object
// get the field IDs for the two instance fields
jfieldID millscndsFieldId = (*env)->GetFieldID(jtimeClazz, "milliscnds", "J"); // 'J' is the JNI type signature for long
jfieldID secsFieldId = (*env)->GetFieldID(jtimeClazz, "secs", "I"); // 'I' is the JNI type signature for int
// set the fields
(*env)->SetLongField(jtime, millscndsFieldId, (jlong)mytime.milliscnds);
(*env)->SetIntField(jtime, secsFieldId, (jint)mytime.secs);
}
理想情况下,您应该缓存millscndsFieldId
和secsFieldId
的值,因为它们在执行期间不会更改(如果您jtimeClazz
,也可以缓存NewGlobalRef
)。
此处记录了所有JNI功能:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html