我正在使用JNI在C++和Java之间传递数据。我需要传递“长”类型,并使用类似以下内容的方法:

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

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

最佳答案

当传递jlong​​(64位)作为指针(最有可能是32位)时,您必然会丢失数据。我不确定约定是什么,但是可以尝试以下一种方法:

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

或这个:
CallStaticVoidMethod(myClass, "(J)V", val);

带有jvalue数组的...A方法,无后缀方法采用与标量Java类型等效的C语言。

第一个片段有些不安全;更好的选择(如果更详细)将是:
jvalue jv;
jv.j = val;
CallStaticVoidMethodA(myClass, "(J)V", &jv);

在某些奇异的CPU体系结构上,jlong变量和jvalue并集的对齐要求可能会有所不同。当您显式声明一个 union 时,编译器会进行处理。

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

07-27 23:02