In my native code I generate a vector of float and need to send this to java part by converting it to byte array (using little endian scheme). Later I resend this byte array and need to convert it back to original float vector. I could not find exact example and wrote below code, that will take 4 byte values at a time and will convert it to float and add it to final vector of float. I will not be modifying any of the data, just perform some calculations, so need it to be fast and if possible avoid memory copy wherever possible.
Currently it is giving me warning that "Using unsigned char for signed value of type jbyte". Can someone guide me how to proceed?
JNIEXPORT jfloat JNICALL Java_com_xyzxyzxcyzxczxczc(JNIEnv *env, jclass type, jlong hEngineHandle, jbyteArray feature1){
try {
PeopleCounting *obj = (PeopleCounting *) hEngineHandle;
jbyte *f1 = (jbyte *)env->GetByteArrayElements(feature1, NULL);
if(obj->faceRecognitionByteArraySize == 0){ // Setting it once for future use as it not going to change for my use case
obj->faceRecognitionByteArraySize = env->GetArrayLength(feature1);
}
union UStuff
{
float f;
unsigned char c[4];
};
UStuff f1bb;
std::vector<float> f1vec;
//Convert every 4 bytes to float using a union
for (int i = 0; i < obj->faceRecognitionByteArraySize; i+=4){
//Going backwards - due to endianness
// Warning here. // Using unsigned char for signed value of type jbyte
f1bb.c[3] = f1[i];
f1bb.c[2] = f1[i+1];
f1bb.c[1] = f1[i+2];
f1bb.c[0] = f1[i+3];
f1vec.push_back(f1bb.f);
}
// release it
env->ReleaseByteArrayElements(feature1, f1, 0 );
// Work with f1vec data
}
UPDATES: As suggested by @Alex both consumer and producer of byte array will be the C++ then there is no need for any endianess. So the approach I am going to take is as below:
A) Java end I initialize a byte[] of needed length (4 * number of float values) B) Pass this as jbyteArray to JNI function
Now, How to fill this byteArray from C++ end?
JNIEXPORT void JNICALL Java_com_xyz_FaceRecognizeGenerateFeatureData(JNIEnv *env, jclass type, jlong hEngineHandle, jlong addrAlignedFaceMat, jbyteArray featureData){
try {
PeopleCounting *obj = (PeopleCounting *) hEngineHandle;
Mat *pMat = (Mat *) addrAlignedFaceMat;
vector<float> vecFloatFeatureData = obj->faceRecognizeGenerateFeatureData(*pMat);
void* data = env->GetDirectBufferAddress(featureData); // How to fill the byteArray with values from vecFloatFeatureData? (If requied I can have a constant having the length of the array or number of actual float values i.e. len of array/4
C) Now, later on I need to consume this data again by passing this from Java to C++. So passing the jbyteArray to the JNI function
JNIEXPORT jfloat JNICALL Java_com_xyz_ConsumeData(JNIEnv *env, jclass type, jlong hEngineHandle, jbyteArray feature1){
try {
PeopleCounting *obj = (PeopleCounting *) hEngineHandle;
void* data = env->GetDirectBufferAddress(featureData);
float *floatBuffer = (float *) data1;
vector<float> vecFloatFeature1Data(floatBuffer, floatBuffer + obj->_faceRecognitionByteArraySize); // _faceRecognitionByteArraySize contains the byte array size i.e. 4*no. of floats
Would this work?