将java字符串作为c/c++;字节

将java字符串作为c/c++;字节,java,android,c++,boost,tcp,Java,Android,C++,Boost,Tcp,我正在开发一个充当TCP服务器/客户端的Android应用程序。我想将数据从该应用程序发送到一个用c/c++编写的服务器/客户端(用boost libraray制作)。我有一个普通的Java函数,它调用一个本机c函数来将字符串转换为字节: 函数定义如下(本机函数为Convert String: // Send buffer, the method can be used by both client and server objects. public void SendBuffer(Strin

我正在开发一个充当TCP服务器/客户端的Android应用程序。我想将数据从该应用程序发送到一个用c/c++编写的服务器/客户端(用boost libraray制作)。我有一个普通的Java函数,它调用一个本机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字节的形式返回,定义如下:

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”,但不是作为一个完整的数组(因此没有“AAAAA DD”)。我认为问题在于服务器一次发送2个“AAAA”,而不是整个数组。客户端崩溃时出现以下错误:

'boost::exception\u detail::clone\u impl>' what():读取:文件结束


java服务器是否发送了错误的数据?有人能给我一个建议吗?欢迎所有反馈!

您愿意发送数据还是让JNI工作起来? 在前一种情况下,使用Java将字符串转换为UTF-8(英文为ASCII)

文本字节[]->字节[]的转换并不完全是您所需要的,但您会明白:

//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;
}
在我手边的代码里
我没有使用JString,更喜欢字节数组。

Hi,谢谢你的回答!我想让JNI的东西工作起来,字符串数据的发送实际上是我实现主要目标的一个垫脚石。那就是发送一个Opencv Mat(本机格式)variabele从android到我的TCP客户端查看。你有什么建议吗?谢谢!Mat变量问题的第二种情况的代码是?还是我的原始问题?代码是工作代码,但它不能解决你的问题。它只是一段使用SetByteArrayRegion()和GetByteArrayRegion()的工作代码.changeEncoding()JNI函数调用一个java函数,该函数将文本从一种编码转换为另一种编码。它可能对您有用,也可能不有用。无论如何,我认为最好先让TCP工作,然后让JNI工作。反之亦然,但不要同时调试这两种编码。感谢我让TCP工作,我发现我确实正确地关闭了连接发送后,第二次发送操作将失败。您知道是否有方法将java bytebuffer转换为本机字符缓冲区,以便提取整数数据?