JNI 日期值转换问题,在C++中获取不同的长整型值

JNI date value conversion issue, getting a different long value in C++

本文关键字:获取 长整型 转换 日期 问题 JNI C++      更新时间:2023-10-16

我在jni中严重陷入了一个基本的日期转换,因为从Java传递到JNI/C++的(长(值完全不同。 我的 Java 日期对象在类中初始化为

Date date1=new Date(1220227200L * 1000);
// If I convert into milliseconds such as 
long timeInMillisecond=date1.getTime();
System.out.println (timeInMillisecond )
// it obviously displays 1220227200000

在我的本机函数中,我正在检索为

jfieldID fid = env->GetFieldID(cls, "date1", "Ljava/util/Date");
// case 1 - value 1
jlong dobject =  (jlong) env->GetObjectField(object ,fid);
cout <<dobject;     //displays 139757766370904
// case 2 - value 2
long dobject2 = (long) env->GetObjectField(object, fid);
cout <<dobject2;  // displays 140031771862616
// case 3 - value 3
long long dobject3 = (long long) env->GetObjectField(object ,fid);
cout <<dobject3; //displays  140456034100824

我想知道在C++从 Java 获得正确值的最佳方法是什么。我正在使用C++ 11。有人请在这里帮助我。

更新对不起,伙计们,我想我拼错了一些变量,所以它不是 GetObjectfield 中的 dobject2,3(更正它(并且实际上在这里重写代码以使其更清晰。

//Data.java
class Data {
public long sDate;
public Date schedDate;
....
}
// Test.java    
// Native function
public native static void sendEvent(Data EventRec);
Data Rec= new DataRec();
Rec.sDate= 1400754723399L;
Rec.schedDate = new Date(1220227200L * 1000);
sendEvent(Rec);
//C++
JNIEXPORT void JNICALL Java_Test_sendEvent  (JNIEnv *env, jclass cls, jobject jobj) {
cls = env->FindClass("Data");
if (cls !=NULL) {
jmethodID ctorID = env->GetMethodID(cls, "<init>","()V");
if (ctorID != NULL) {
jfieldID fidLong = env->GetFieldID(cls, "sDate", "J");
long dObj = (long) env->GetLongField(jobj,fidLong);
cout << "C++ .. Event Date (LONG): " << dObj <<endl; // This is correct  
jfieldID fidDate = env->GetFieldID(cls, "schedDate", "Ljava/util/Date");
// Here is the problem area, that I tried to mimic above...             
jobject dobject= (env->GetObjectField(jobj,fidDate));
long dobj = env->GetLongField(dobject,fidDate);
// OR 
// long dObj2 = (long) env->GetLongField(jobj,fidDate);
// ..... 
cout << "C++ .. Date (DATE)..." << dobj;
}
}   
}

您的 JNI 代码未正确访问 Java 对象。

Java_Test_sendEvent()实现中,jclass参数指向声明public native static void sendEvent(Data EventRec);的类类型(未显示(,jobject参数指向Java代码传递给sendEvent()Data Rec对象。

此外,在调用Date字段的env->GetFieldID()时,类型签名字符串的末尾缺少必需的分号。

试试这个:

JNIEXPORT void JNICALL Java_Test_sendEvent  (JNIEnv *env, jclass cls, jobject EventRec)
{
jclass cls_EventRec = env->GetObjectClass(EventRec);
jfieldID fid_sDate = env->GetFieldID(cls_EventRec, "sDate", "J");
if (!fid_sDate) {
// error handling...
return;
}
jfieldID fid_schedDate = env->GetFieldID(cls_EventRec, "schedDate", "Ljava/util/Date;");
if (!fid_schedDate) {
// error handling...
return;
}
jlong sDate = env->GetLongField(EventRec, fid_sDate);
cout << "C++ .. Event Date (LONG): " << sDate << endl;
jobject schedDate = env->GetObjectField(EventRec, fid_schedDate);
if (schedDate) {
jclass cls_schedDate = env->GetObjectClass(schedDate);
jmethodID mid_getTime = env->GetMethodID(cls_schedDate, "getTime", "()J"); 
jlong timeInMillisecond = env->CallLongMethod(schedDate, mid_getTime);
cout << "C++ .. Date (DATE)..." << timeInMillisecond << endl;
}
}

你忽略了一些非常重要的东西:

jfieldID fid = env->GetFieldID(cls, "date1", "Ljava/util/Date;");
jobject dobject = env->GetObjectField(dobject, fid); // Note: "Get Object Field"

这将返回一个java.util.Date对象。您还需要调用getTime

jmethodID mid = env->GetMethodID(cls, "getTime", "()J"); 
jlong timeInMillisecond = env->CallLongMethod(dobject, mid);