Search code examples
ccastingandroid-ndkjava-native-interface

Type casting for printf but not otherwise


I am trying to convert from bytes to float in JNI. If I type cast it when calling the GetByteArrayElements method, it does not work. Printing out the float variable prints out a pointer instead. I know it is a pointer because usually it is something like "123451234993305848212225.000000" However, if I type cast it as float in the printf statement, it displays the correct value. Why does this happen? I have the two sets of code fragments below -

jbyte *testTensor_data = (env)->GetByteArrayElements(NV21FrameData,0);
__android_log_print(ANDROID_LOG_INFO, "Torchandroid", "C test print: %f",(float) (testTensor_data[0]));

This works. The print statement displays the correct number.

jfloat *testTensor_data = (float*) (env)->GetByteArrayElements(NV21FrameData,0);
__android_log_print(ANDROID_LOG_INFO, "Torchandroid", "C test print: %f",(testTensor_data[0]));

This second method does not work. Problem is, simply printing out a float is not useful to me. I need to use it as a float and manipulate it as a float which is the second method and it doesn't work.


Solution

  • The examples are not equal. testTensor_data[0] is a jbyte (sizeof(jbyte)==1) in the first case, and a float (sizeof(jfloat)==4) in the second case. It's not a pointer it is printing, but about 4 bytes that are casted into a single float.

    In order to handle 12bit data with some convinience, you can do something like:

    struct 3pix {
        int a:12;
        int b:12;
    };
    

    in the hope that it will not be padded, and then accessing ((struct 3pix*)test_Tensor_data)->a or something like that. I think it won't be easy. Another solution - more natural - is to use bitwise operations, but you'll have to get the calculations right.