如何将NULL分配给float / double变量?

时间:2015-06-09 15:25:42

标签: c java-native-interface

使用JNI时遇到问题。

jboolean z = (jboolean) NULL; // ok
jbyte    b = (jbyte)    NULL; // ok
jchar    c = (jchar)    NULL; // ok
jshort   s = (jshort)   NULL; // ok
jint     i = (jint)     NULL; // ok
jlong    j = (jlong)    NULL; // ok

jobject  l = (jobjec)   NULL; // ok

jfloat   f = (jlong)     NULL; // NOT OK 
jdouble  d = (jdouble)   NULL; // NOT OK

编译器抱怨

[ERROR] /....c:112:28: error: pointer cannot be cast to type 'jfloat' (aka 'float')
[ERROR]   jfloat result = (jfloat) NULL;
[ERROR]                            ^~~~
[ERROR] /usr/include/sys/_types/_null.h:29:15: note: expanded from macro 'NULL'
[ERROR] #define NULL  __DARWIN_NULL
[ERROR]               ^~~~~~~~~~~~~
[ERROR] /usr/include/sys/_types.h:52:23: note: expanded from macro '__DARWIN_NULL'
[ERROR] #define __DARWIN_NULL ((void *)0)
[ERROR]                       ^~~~~~~~~~~
[ERROR] 1 error generated.

我该如何解决这个问题?

我正在为每个值编写方法。

jboolean doSome() {
    jboolean result = (jboolean) NULL;
    /*
     * at here result may be initialized or remain as NULL
     */
    return result;
}

我打算写一个函数结合以下三种方法。

(*env)->GetObjecClass(JNIEnv *, jobject);
(*env)->GetMethodID(JNIEnv *, jclass, char *, char *);
(*env)->CallBooleanMethodA(JNIEnv *, jclass, jmethodID, jvalue *);
像这样。

jboolean CallBooleanMethodAMmMs(JNIEnv * env, jobject obj, char * mname,
                                char * msig, jvalue * args) {
  jboolean result = (jboolean) NULL;
  jclass clazz = (*env)->GetObjectClass(env, obj);
  jmethodID methodID = (*env)->GetMethodID(env, clazz, mname, msig);
  if (methodID != NULL) {
    result = (*env)->CallBooleanMethodA(env, obj, methodID, args);
  }
  (*env)->DeleteLocalRef(env, clazz);
  return result;
}

我认为我可以使用NULL来处理任何不成功的情况,例如methodID == NULL

我想我应该使用jobject而不是原语,对吧?

3 个答案:

答案 0 :(得分:4)

您不能(也不应该)将指针分配给普通变量。

我真的不知道为什么它允许其他一些正常的数据类型,正如你所提到的那样。对于从指向其他非指针数据类型的指针的所有赋值,编译器应该同样产生相同的警告

NULL是stdio.h中定义的void指针,用于初始化指针类型变量。如果要初始化非指针变量,请使用简单的0代替NULL

答案 1 :(得分:3)

如果您没有指向的实际对象,

NULL应该用作指针的特殊值。这是Option Types的替代(在其他语言中使用,通常被认为是更好的解决方案)并且仅适用于指针类型(因为对于其他类型,它更容易选择一个值作为值用那个"特殊含义")。

所以NULL的处理方式与任何其他指针的处理方式相同。虽然指针转换为整数类型在某些特殊情况下仍然有意义(即使它很危险,因为根据类型你可能会截断指针),将它转换为指针肯定没有任何意义。一个浮点数(它们用于数值计算,对内存地址没有意义)。

无论如何,你想要实现什么目标?如果只是将这些变量初始化为明确定义的初始值,请尝试0.0f0.0而不是NULL

答案 2 :(得分:2)

  

如何将NULL分配给float / double变量?

使用intptr_t/uintptr_t这些整数类型可以保存void *的信息。

这将保留再次void *所需的信息,与NULL平等对比。

 intptr_t iptr = (intptr_t) NULL;
 void *ptr = (void *) iptr;
 assert(ptr == NULL);

这会将整数转换为double,但信息(例如精度)可能会丢失。如果代码尝试转换回intptr_t,然后void *,然后尝试与NULL进行同等比较,则可能会失败。

 intptr_t iptr = (intptr_t) NULL;
 double fp = (double) iptr;

 intptr_t iptr2 = (intptr_t) fp;
 void *ptr = (void *) iptr2;

 // May not succeed
 assert(ptr == NULL);