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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7536439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:23:15  来源:igfitidea点击:

Casting a C++ long type to a JNI jlong

javaandroidc++java-native-interfaceandroid-ndk

提问by lost_bits1110

I am using JNI to pass data between C++ and Java. I need to pass a 'long' type, and am doing so using something like:

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

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

However in Java, when the 'long' parameter is retrieved, it gets retrieved as some very large negative number. What am I doing wrong?

然而,在 Java 中,当检索“long”参数时,它会被检索为某个非常大的负数。我究竟做错了什么?

回答by Seva Alekseyev

When you pass a jlong (which is 64 bit) as a pointer (which is, most likely, 32-bit) you necessarily lose data. I'm not sure what's the convention, but try either this:

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

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

or this:

或这个:

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

It's ...Amethods that take a jvalue array, the no-postfix methods take C equivalents to scalar Java types.

...A是采用 jvalue 数组的方法,无后缀方法采用 C 等效于标量 Java 类型。

The first snippet is somewhat unsafe; a better, if more verbose, alternative would be:

第一个片段有点不安全;更好的,如果更详细的话,替代方法是:

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

On some exotic CPU archtectures, the alignment requirements for jlongvariables and jvalueunions might be different. When you declare a union explicitly, the compiler takes care of that.

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

Also note that C++ longdatatype is often 32-bit. jlong is 64 bits, on 32-bit platforms the nonstandard C equivalent is long longor __int64.

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

回答by Puppy

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

This is undefined behaviour. You are casting an integer to be a pointer. It is not a pointer. You need, at the very least, to pass the address. This code would on most platforms instantly crash.

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