I have the following JNI function:
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
int bar(ULONG id, ULONG *val);
where ULONG
is
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
. 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
.
java.util.Long
provides method to create unsigned String value from 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.
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
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.