我正在使用JNI在C ++和Java之间传递数据。我需要传递一个'long'类型,并且使用类似的东西:
long myLongVal = 100;
jlong val = (jlong)myLongVal;
CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val);
但是在Java中,当检索到'long'参数时,它会被检索为一些非常大的负数。我究竟做错了什么?
答案 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);
这是未定义的行为。您正在转换整数作为指针。它不是指针。您至少需要传递地址。这段代码会在大多数平台上立即崩溃。