我正在开发一个充当 TCP 服务器/客户端的 Android 应用程序我想将数据从应用程序发送到用 c/c++(使用 boost 库制作)编写的服务器/客户端。我有一个普通的 Java 函数调用 native c 函数将字符串转换为字节:
函数定义如下(原生函数为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();
}
}
ConvertString 函数是将Java 字符串转换为C/C++ 字符串并以Java 字节形式返回的 native 函数,其定义如下:
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;
}
当我运行程序时,我在 c 端得到两个“AAAA”,但不是整个数组(所以没有“AAAAAAAADD”)。我认为问题在于服务器一次发送 2 个“AAAA”而不是整个数组。客户端崩溃并出现以下错误:
'boost::exception_detail::clone_impl >' what(): 读取:文件结束
java服务器是否发送数据错误?谁能给我一个建议?欢迎所有反馈!
最佳答案
您愿意发送数据还是让 JNI 工作? 在前一种情况下,使用 Java 将字符串转换为 UTF-8(英语为 ASCII。)
文本 byte[] -> byte[] 的转换并不是你所需要的,但你会明白的:
//byte[] result;
//byte[] source;
String s = new String(source,"UTF-8");
result = s.getBytes("UTF-16LE");
对于第二种情况,我可以分享一部分工作代码;它调用 Java 将一种编码转换为另一种编码
// 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;
}
在我手边的代码中 我没有使用 jstrings,更喜欢字节数组。
关于java - 将 java 字符串作为 c/c++ 字节发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21109382/