将C ++ long类型转换为JNI jlong

时间:2011-09-24 01:48:49

标签: java android c++ java-native-interface android-ndk

我正在使用JNI在C ++和Java之间传递数据。我需要传递一个'long'类型,并且使用类似的东西:

 long myLongVal = 100;
 jlong val = (jlong)myLongVal;
 CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val);

但是在Java中,当检索到'long'参数时,它会被检索为一些非常大的负数。我究竟做错了什么?

2 个答案:

答案 0 :(得分:12)

当你将jlong​​(64位)作为指针(很可能是32位)传递时,你必然会丢失数据。我不确定这是什么惯例,但试试这个:

CallStaticVoidMethodA(myClass, "(J)V", (jvalue*)&val); //Note address-of!

或者这个:

CallStaticVoidMethod(myClass, "(J)V", val); 

采用jvalue数组的...A方法,无后缀方法将C等价物转换为标量Java类型。

第一个片段有些不安全;一个更好的,如果更详细的替代方案将是:

jvalue jv;
jv.j = val;
CallStaticVoidMethodA(myClass, "(J)V", &jv);

在某些奇特的CPU架构中,jlong变量和jvalue联合的对齐要求可能不同。当您明确声明一个联合时,编译器会处理它。

另请注意,C ++ long数据类型通常为32位。 jlong​​是64位,在32位平台上,非标准C等价物是long long__int64

答案 1 :(得分:3)

CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val);

这是未定义的行为。您正在转换整数作为指针。它不是指针。您至少需要传递地址。这段代码会在大多数平台上立即崩溃。