Home Help Center

Encoding Problem about Chinese, client compiled by Java, server compiled by C++

richardmarichardma Member richardOrganization: qqProject: wap ✭✭
a project server compiled by C++ and client compiled by java for display, but a problem comes when Chinese display.
when I compiled client by C++, the Chinese display is normal, but when I compiled client by java, the Chinese display isn't normal, that's disorder.
Now I solved it by update the source, under directory "src/IceInternal".
If there others way solve it, such as update config etc.??

Comments

  • benoitbenoit Rennes, FranceAdministrators, ZeroC Staff Benoit FoucherOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    Hello,

    I'm afraid we can't help you without more information about your problem. Could you post the sample source code that demonstrates the problem? How do you print the strings in the C++ and Java client for instance?

    Also, what did you change in src/IceInternal to get it to work?

    Benoit.
  • richardmarichardma Member richardOrganization: qqProject: wap ✭✭
    my code as follows:

    ice definition:
    #ifndef HELLO_ICE
    #define HELLO_ICE

    module Demo
    {

    interface Hello
    {
    nonmutating void sayHello();
    };

    };

    #endif



    C++ implement server:
    HelloI::sayHello(const Ice::Current&) const
    {
    cout << "Hello World!哈哈哈哈哈哈哈" << endl;
    }

    when java client call 'sayHello' on windows the result is:
    Hello World!?????????


    The source I update is:
    the directory: IceJ-2.1.2/src/IceInternal
    the file :BasicStream.java
    I note the 'UTF8' encode is the main modification.
    the result of differ as follow:
    diff -r IceJ-2.1.2.1/src/IceInternal/BasicStream.java IceJ-2.1.2/src/IceInternal/BasicStream.java
    1038c1038
    < // try
    ---
    > try
    1040,1041c1040
    < //byte[] arr = v.getBytes("UTF8");
    < byte[] arr = v.getBytes();
    ---
    > byte[] arr = v.getBytes("UTF8");
    1046,1049c1045,1048
    < // catch(java.io.UnsupportedEncodingException ex)
    < // {
    < // assert(false);
    < // }
    ---
    > catch(java.io.UnsupportedEncodingException ex)
    > {
    > assert(false);
    > }
    1121,1122c1120
    < //return new String(_stringBytes, 0, len, "UTF8");
    < return new String(_stringBytes, 0, len);
    ---
    > return new String(_stringBytes, 0, len, "UTF8");
    1131c1129
    < /* catch(java.io.UnsupportedEncodingException ex)
    ---
    > catch(java.io.UnsupportedEncodingException ex)
    1136c1134
    < */ catch(java.nio.BufferUnderflowException ex)
    ---
    > catch(java.nio.BufferUnderflowException ex)
  • benoitbenoit Rennes, FranceAdministrators, ZeroC Staff Benoit FoucherOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    Is this really the code you're using? The code you posted doesn't receive a string over the wire, it just prints a string on the standard error output so I don't see how invoking the sayHello() method would print different strings if invoked from a C++ client or Java client.

    It's also not quite clear from the diff output what are the changes you made. Could you just post your BasicStream.java file with your modifications as an attachment?

    Benoit.
  • richardmarichardma Member richardOrganization: qqProject: wap ✭✭
    Because the code I using is much, I didn't paste it. I only want to explain the phenomenon that display the Chinese through the code as above, it isn't the code I using.

    the BasicStream.java I modified as follow:
    public void
    writeString(String v)
    {
    if(v == null)
    {
    writeSize(0);
    }
    else
    {
    final int len = v.length();
    if(len > 0)
    {
    // try
    {
    //byte[] arr = v.getBytes("UTF8");
    byte[] arr = v.getBytes();
    writeSize(arr.length);
    expand(arr.length);
    _buf.put(arr);
    }
    // catch(java.io.UnsupportedEncodingException ex)
    // {
    // assert(false);
    // }
    }
    else
    {
    writeSize(0);
    }
    }
    }

    public void
    writeStringSeq(String[] v)
    {
    if(v == null)
    {
    writeSize(0);
    }
    else
    {
    writeSize(v.length);
    for(int i = 0; i < v.length; i++)
    {
    writeString(v);
    }
    }
    }

    public String
    readString()
    {
    final int len = readSize();

    if(len == 0)
    {
    return "";
    }
    else
    {
    try
    {
    //
    // We reuse the _stringBytes array to avoid creating
    // excessive garbage
    //
    if(_stringBytes == null || len > _stringBytes.length)
    {
    _stringBytes = new byte[len];
    _stringChars = new char[len];
    }
    _buf.get(_stringBytes, 0, len);

    //
    // It's more efficient to construct a string using a
    // character array instead of a byte array, because
    // byte arrays require conversion.
    //
    for(int i = 0; i < len; i++)
    {
    if(_stringBytes < 0)
    {
    //
    // Multi-byte character found - we must use
    // conversion.
    //
    // TODO: If the string contains garbage bytes
    // that won't correctly decode as UTF, the
    // behavior of this constructor is
    // undefined. It would be better to explicitly
    // decode using
    // java.nio.charset.CharsetDecoder and to
    // throw MarshalException if the string won't
    // decode.
    //
    //return new String(_stringBytes, 0, len, "UTF8");
    return new String(_stringBytes, 0, len);
    }
    else
    {
    _stringChars = (char)_stringBytes;
    }
    }
    return new String(_stringChars, 0, len);
    }
    /* catch(java.io.UnsupportedEncodingException ex)
    {
    assert(false);
    return "";
    }
    */ catch(java.nio.BufferUnderflowException ex)
    {
    throw new Ice.UnmarshalOutOfBoundsException();
    }
    }
    }
  • bernardbernard Jupiter, FLAdministrators, ZeroC Staff Bernard NormierOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    Since the string displayed by your C++ program is not transmitted by Ice, Ice is not involved. And your change to the Ice source code does not help.

    In C++, to display wide-strings, you should use wcout, e.g.:
    wcout << L"Hello World [chinese characters]" << endl;

    Cheers,
    Bernard
  • lifejoylifejoy Member lifejoyOrganization: klmtProject: 1919&secondplat
    Re
    bernard wrote:
    Since the string displayed by your C++ program is not transmitted by Ice, Ice is not involved. And your change to the Ice source code does not help.

    In C++, to display wide-strings, you should use wcout, e.g.:
    wcout << L"Hello World [chinese characters]" << endl;

    Cheers,
    Bernard
    In C++ Service you should encoding you local text to UTF-8, then you can receive correct message in java client ,so you can encoding you message text in java with GB2312! good luck!
Sign In or Register to comment.