В своем нативном коде я генерирую вектор с плавающей точкой, и мне нужно отправить его в java часть путем преобразования его в байтовый массив (используя схему с прямым порядком байтов). Позже я пересылаю этот байтовый массив и мне нужно преобразовать его обратно в исходный вектор с плавающей точкой. Я не смог найти точный пример и написал ниже код, который будет принимать 4-байтовые значения за раз и будет преобразовывать его в float и добавлять его в конечный вектор float. Я не буду изменять какие-либо данные, просто выполню некоторые вычисления, поэтому нужно, чтобы они были быстрыми и, если возможно, избегали копирования памяти, где это возможно.
В настоящее время я предупреждаю, что «Использование знака без знака для значения со знаком типа jbyte ". Кто-нибудь может подсказать мне, как поступить?
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
}
ОБНОВЛЕНИЯ: Как предполагает @Alex, и потребителем, и производителем байтового массива будет C ++, тогда нет необходимости в какой-либо последовательности. Таким образом, подход, который я собираюсь предпринять, выглядит следующим образом:
A) Java end Я инициализирую байт [] необходимой длины (4 * число значений с плавающей запятой). B) Передайте это как jbyteArray в функцию JNI.
Теперь, Как заполнить этот byteArray из конца C ++ ?
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) Теперь, позже мне нужно снова использовать эти данные, передав эту от Java до C ++. Поэтому передача jbyteArray в функцию JNI
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
Будет ли это работать?