开发者

Casting a C++ long type to a JNI jlong

开发者 https://www.devze.com 2023-04-07 09:28 出处:网络
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:

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:

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

However in Java, when the 'long' parameter is retrie开发者_运维技巧ved, it gets retrieved as some very large negative number. What am I doing wrong?


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:

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.

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.

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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消