[英]Casting jlong to and from unsigned long int
I have the following JNI function: 我具有以下JNI函数:
JNIEXPORT jint JNICALL foo(JNIEnv *env, jobject obj, jlong id, jlongArray array)
{
jboolean isCopy;
jsize len = (*env)->GetArrayLength(env, array);
jlong* lp = (*env)->GetLongArrayElements(env, array, &isCopy);
if (!lp) {
return INSUFFICIENT_RESOURCES;
}
jlong retval = 0;
// insert code to cast id from jlong to ULONG before passing to bar(...)?
jint ret = bar(id, &retval);
if(len>=1) {
// insert code to cast retval from ULONG back to jlong
lp[0] = retval;
}
int mode = 0;
// if error code is returned then do not save changes
if(ret != 0) {
mode = JNI_ABORT;
}
(*env)->ReleaseLongArrayElements(env, array, lp, mode);
return ret;
}
Method bar
has the signature 方法
bar
有签名
int bar(ULONG id, ULONG *val);
where ULONG
is ULONG
在哪里
typedef ULONG unsigned long int;
So in my JNI function I would like to cast parameter id
from jlong
to ULONG
, and then retval
from ULONG
back to jlong
. 所以在我的JNI功能,我想投参数
id
从jlong
到ULONG
,然后retval
从ULONG
回jlong
。 Can I directly cast, or is there a series of bitwise operations that I can do in these two cases? 我可以直接进行转换,还是在这两种情况下可以执行一系列按位操作?
I know that this solution is a hack, but maybe you can go via String
. 我知道此解决方案是一种技巧,但也许您可以通过
String
。
java.util.Long
provides method to create unsigned String value from long
: java.util.Long
提供了从long
创建无符号String值的方法:
https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#toUnsignedString-long- https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#toUnsignedString-long-
It means, you can always convert your long value (assuming that you make sure it's not negative and in the range of unsigned long
) to String
, pass it to JNI
based code, and convert it back. 这意味着,您始终可以将您的long值(假设您确保它不是负数并且在
unsigned long
的范围内)转换为String
,将其传递给基于JNI
的代码,然后将其转换回。
Java 爪哇
public static void main(String[] args) {
long value_min = 0;
// I assume that we are dealing with 32bit unsigned long on a C side
// if you try to test boundary case with 4294967296L it fill fail for
// 64bit macOS/Linux as you will be able to fit the value into variable.
long value_max = 4294967295L;
System.out.println("I am passing: " + value_min);
PassLongAsString.passULong(java.lang.Long.toUnsignedString(value_min));
System.out.println("I am passing: " + value_max);
PassLongAsString.passULong(java.lang.Long.toUnsignedString(value_max));
}
C C
JNIEXPORT void JNICALL Java_recipeNo058_PassLongAsString_passULong
(JNIEnv * env, jclass obj, jstring str) {
//we have to get string bytes into C string
const char *c_str;
c_str = (*env)->GetStringUTFChars (env, str, NULL);
if (c_str == NULL) {
return;
}
printf ("Passed string: %s\n", c_str);
unsigned long ul = strtoul (c_str, NULL, 0);
printf ("Parsed value: %lu\n", ul);
//after using it, remember to release the memory
(*env)->ReleaseStringUTFChars (env, str, c_str);
}
Of course, it will fail if you will pass value 当然,如果您传递价值,它将失败
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.