49305

Sending java string as c/c++ bytes

Question:

I'm working on a Android app that acts as TCP server/client i want to send data from the app to a server/client that is written in c/c++(made with the boost libraray). I have a normal Java function that calls a native c function for string converstion to bytes:

The function is defined as followed (the native function is Convert String:

// Send buffer, the method can be used by both client and server objects. public void SendBuffer(String Buffer){ try { // Convert char to string to byte byte[] Temp = new byte[10]; String Teststring = "AAAAAAAABB"; Temp = ConvertString(Teststring); //byte[] Temp = new String(Buffer).getBytes(); // Get socket output stream OutputStream OutputBuffer = ClientSocket.getOutputStream(); //Write byte data to outputstream OutputBuffer.write(Temp); // Neatly flush and close the outputbuffer OutputBuffer.flush(); OutputBuffer.close(); } catch (IOException e) { Log.e("TCPIPCommunicator: ", "Client: Failed to send", e); e.printStackTrace(); } }

The function ConvertString is a native function that converts the Java string to a C/C++ string and returns it as Java bytes, it is defined as followed:

JNIEXPORT jbyteArray JNICALL Java_com_example_communicationmoduleTCPIP_communicationmoduleTCPIP_ConvertString( JNIEnv * env, jobject, jstring Buffer) { // Array to fill with data jbyteArray Array; // Init java byte array Array = env->NewByteArray(10); const char* NewBuffer = env->GetStringUTFChars(Buffer, 0); // Set byte array region with the size of the SendData CommStruct. // Now we can send the data back. env->SetByteArrayRegion(Array, 0, 10, (jbyte*)NewBuffer); env->ReleaseStringUTFChars(Buffer, NewBuffer); // Return java array return Array; }

}

When i run the program i get two 'AAAA' on the c side but not as a whole array ( so no 'AAAAAAAADD). I think the problem is that the server sends 2 'AAAA' and not the whole array at once. The client crashes with the following error:

'boost::exception_detail::clone_impl >' what(): read: End of file

Does the java server sends the data wrong? can anyone give me a suggestion? all feedback is welcome!

Answer1:

Are you willing to send the data or to make the JNI stuff work? In the former case, use Java to convert a string into UTF-8 (which will be ASCII for English.)

Conversion of text byte[] -> byte[] is not exactly what you need, but you'll get the idea:

//byte[] result; //byte[] source; String s = new String(source,"UTF-8"); result = s.getBytes("UTF-16LE");

For the 2nd case, I can share a portion of working code; it calls Java to convert from one encoding to another

// it returns NULL in the case of an exception // the returned memory is calloc()'d; it's the caller's responsibility to free() it. char* changeEncoding(const char*source, int len, int direction) { JNIEnv* env = threadUnsafeInfo.env; jobject obj = threadUnsafeInfo.obj; if (!source) { JNU_ThrowByName(env, "java/lang/NullPointerException", 0); return NULL; } jbyteArray srcArray = env->NewByteArray(len); jclass cls = env->FindClass("com/xyz/MyClass"); jmethodID mid = env->GetMethodID(cls, "convert", "([BI)[B"); if (mid != NULL && srcArray != NULL) { env->SetByteArrayRegion(srcArray, 0, len, (jbyte*)source); env->ExceptionClear(); //jbyteArray resArray = (jbyteArray)env->CallStaticObjectMethod(cls, mid, srcArray, direction); jbyteArray resArray = (jbyteArray)env->CallObjectMethod(obj, mid, srcArray, direction); if(env->ExceptionOccurred()) { DLOG("exception in convert ([BI)[B"); env->ExceptionDescribe(); //env->ExceptionClear(); // ?? return NULL; } int resultLen = env->GetArrayLength(resArray); char* result = (char*)calloc(2 + resultLen,1); // why 2: a bit of healthy paranoia ain't gonna hurt anyone if (result == 0) { JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0); return NULL; } env->GetByteArrayRegion(resArray, 0, resultLen, (jbyte *)result); env->DeleteLocalRef(cls); env->DeleteLocalRef(resArray); env->DeleteLocalRef(srcArray); return result; } else { JNU_ThrowByName(env, "java/lang/NullPointerException", 0); myassert(("method id = 0",0)); } return NULL; }

In the code that I have at hand I did not use jstrings, preferring the byte arrays.

Recommend

  • JNI method: formal argument lists differ in length
  • Android Java JNI and C Char array Can't recognize the value
  • No implementation found for native Lcom/jp/algi/
  • Sending java string as c/c++ bytes
  • Java JNI: Passing multibyte characters from java to c
  • convert c++ map to jobject JNI?
  • I have 2 very similar C functions being called from python and Java. How can I combine the 2 librari
  • Problems compiling DLL using GCC on Windows
  • Select from multiple slices in Numpy
  • ColdFusion - DateTime Format with GMT offset
  • Property file in java
  • How to solve “fatal: relocations remain against allocatable but non-writable sections” while using J
  • Retrofit 2 error: NetworkOnMainThreadException
  • UIImageJPEGRepresentation giving 2x images on retina display
  • Excel Date field value differs from c# dateTime by 1 day while reading excel file with EEPlus
  • How to handle empty space in url when downloading image from web?
  • Streaming screenshots over WebRTC as a video stream from iOS
  • Problem with rejecting incoming call
  • How to copy styled text in JTextPane
  • Row to Column conversion in Talend
  • pillow imaging ImportError
  • Check for zero lines output from command over SSH
  • Problems installing Yesod for Haskell
  • Spring Cloud Microservice Architecture Confusion
  • Unable to install Git-core+svn by MacPorts
  • Transactional Create with Validation in ServiceStack Redis Client
  • VSO Build — Response status code does not indicate success: 404 (Not Found)
  • Handling un-mapped Rest path
  • ilmerge with a PFX file
  • PHP - How to update data to MySQL when click a radio button
  • Volley JsonObjectRequest send headers in GET Request