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

los*_*110 12 c++ java java-native-interface android android-ndk

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

 long myLongVal = 100;
 jlong val = (jlong)myLongVal;
 CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val);
Run Code Online (Sandbox Code Playgroud)

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

Sev*_*yev 13

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

CallStaticVoidMethodA(myClass, "(J)V", (jvalue*)&val); //Note address-of!
Run Code Online (Sandbox Code Playgroud)

或这个:

CallStaticVoidMethod(myClass, "(J)V", val); 
Run Code Online (Sandbox Code Playgroud)

...A采用jvalue数组的方法,no-postfix方法将C等价物转换为标量Java类型.

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

jvalue jv;
jv.j = val;
CallStaticVoidMethodA(myClass, "(J)V", &jv);
Run Code Online (Sandbox Code Playgroud)

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

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

  • "C++ long也是32位" - 在某些架构上是正确的,而在其他架构上则不然.x64 linux通常使用64位长.很长时间都无法在任何地方使用(这是一个扩展IIRC). (3认同)