如果我只想将值设置为Double类型变量,我可以编写如下代码:
public static native int getDoubleVar(Double dobj);
JNIEXPORT jint JNICALL
test_jni_Native_testGet(JNIEnv *env, jclass type, jobject dobj)
{
jclass DoubleClass = env->FindClass("java/lang/Double");
jfieldID valueID = env->GetFieldID(DoubleClass, "value", "D");
env->SetDoubleField(dobj, valueID, 2.3);
return 0;
}
这些代码生效。
但是,当我试图通过JNI设置一个类的“Double”变量的值时,我无法得到我想要的东西,当然,它崩溃了,这让我有点困惑。
Java代码:
public class TestDouble
{
public Double value;
public long num;
public TestDouble(long num, Double value)
{
this.num = num;
this.value = value;
}
}
本机:
public static native int testGet(TestDouble tdobj);
c代码:
JNIEXPORT jint JNICALL
test_jni_Native_testGet(JNIEnv *env, jclass type, jobject tdobj)
{
jclass tdobjClass = env->FindClass("xxxx/TestDouble");
jfieldID valueID = env->GetFieldID(tdobjClass, "value", "D");
env->SetDoubleField(tdobj, jValueID, 2.3);
return 0;
}
我想设置'TestDouble'类的'value'的值,'value'的类型是'Double'(不是double)。
E/dalvikvm: VM aborting
Fatal signal 6
Send stop signal to pid:5830 in void debuggerd_signal_handler(int, siginfo_t*, void*)
我只是在这里粘贴错误的单词,很明显错误发生在:
env->SetDoubleField(tdobj, jValueID, 2.3);
我该怎么办才能解决这个问题呢? 非常感谢!
答案 0 :(得分:3)
我得到了正确答案:
http://stackoverflow.com/questions/34848605/how-to-set-the-value-of-a-double-integer-type-of-a-java-class-by-jni
JNIEXPORT jint JNICALL test_jni_Native_testSet(JNIEnv *env, jclass type, jobject tdobj)
{
//Create Integer class, get constructor and create Integer object
jclass intClass = env->FindClass(env, "java/lang/Integer");
jmethodID initInt = env->GetMethodID(env, intClass, "<init>", "(I)V");
if (NULL == initInt) return -1;
jobject newIntObj = env->NewObject(env, intClass, initInt, 123);
//Now set your integer into value atttribute. For this, I would
//recommend you to have a java setter and call it in the same way
//as shown above
//clean reference
env->DeleteLocalRef(env, newIntObj);
return 0;
}
Integer / Double和其他包装类型可以用同样的方式处理..
答案 1 :(得分:0)
您的C代码假定TestDouble.value
是原始double
而不是对象Double
因此在运行时失败。
您可以将班级定义更改为
public class TestDouble
{
public double value;
public long num;
public TestDouble(long num, double value)
{
this.num = num;
this.value = value;
}
}
答案 2 :(得分:0)
如果您的Double对象已经在JAVA代码中创建,则无需在C ++(抱歉,不是C)部分中创建新的Double对象。您可以执行以下操作:
void setDoubleObjectField(JNIEnv* env, jobject PropertyDoubleObj, char* FieldName, double dValue)
{
jclass PropertyClass = (env)->GetObjectClass(PropertyDoubleObj);
//printf("%s\n",getClassName( env, PropertyDoubleObj));
jfieldID fidNumber = (env)->GetFieldID(PropertyClass, FieldName, "Ljava/lang/Double;");
if (fidNumber == 0)
{
CreateException(env, std::string("Failed to query field from PropertyDouble class: ") + FieldName);
return;
}
jobject DoubleObject = env->GetObjectField(PropertyDoubleObj, fidNumber);
if (DoubleObject == 0) // That means, the object was simply not created. Just create one.
{
jclass DoubleClass = env->FindClass("java/lang/Double");
jmethodID initDouble = env->GetMethodID( DoubleClass, "<init>", "(D)V");
if (NULL == initDouble)
{
CreateException(env, "Failed to create Double object.");
return;
}
DoubleObject = env->NewObject( DoubleClass, initDouble, dValue);
env->SetObjectField(PropertyDoubleObj, fidNumber, DoubleObject);
env->DeleteLocalRef(DoubleObject);
}
else
{
jclass DoubleCls = (env)->GetObjectClass(DoubleObject);
jfieldID fidNumber_double = (env)->GetFieldID(DoubleCls, "value", "D");
if (fidNumber_double == 0)
{
CreateException(env, "Failed to query value field from Double class.");
return;
}
env->SetDoubleField(DoubleObject, fidNumber_double, dValue);
}
}