将一个c++长类型转换为JNI jlong。

时间:2021-12-20 16:43:27

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”类型,并且正在这样做:

 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”参数时,它会被检索为一些非常大的负数。我做错了什么?

2 个解决方案

#1


12  

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 ...A methods that take a jvalue array, the no-postfix methods take C equivalents to scalar Java types.

这是……一种采用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 jlong variables and jvalue unions might be different. When you declare a union explicitly, the compiler takes care of that.

在一些奇异的CPU archtecery中,jlong变量和jvalue结合的对齐要求可能会有所不同。当您显式声明一个联合时,编译器会处理它。

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

还要注意,c++长数据类型通常是32位的。jlong是64位,在32位的平台上,非标准的C等价于long long或__int64。

#2


3  

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.

这是未定义的行为。您正在将一个整数转换为一个指针。它不是一个指针。你至少需要通过这个地址。这段代码会在大多数平台上瞬间崩溃。

#1


12  

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 ...A methods that take a jvalue array, the no-postfix methods take C equivalents to scalar Java types.

这是……一种采用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 jlong variables and jvalue unions might be different. When you declare a union explicitly, the compiler takes care of that.

在一些奇异的CPU archtecery中,jlong变量和jvalue结合的对齐要求可能会有所不同。当您显式声明一个联合时,编译器会处理它。

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

还要注意,c++长数据类型通常是32位的。jlong是64位,在32位的平台上,非标准的C等价于long long或__int64。

#2


3  

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.

这是未定义的行为。您正在将一个整数转换为一个指针。它不是一个指针。你至少需要通过这个地址。这段代码会在大多数平台上瞬间崩溃。