View Single Post
  #1 (permalink)  
Old 10-28-2004
ChaosXu ChaosXu is offline
Registered User
 
 
Join Date: Oct 2004
Posts: 2
Question An error occurs when c# client send chinese string to c++ server

Hi:

An error occurs when c# client send chinese string to the c++ server.
The server can receive the string,but the result of unmarshal is wrong,
and an assert appears when release the memory of string.so I browse
the source code of ice and icecs,I see these:

basicstream.cpp:
void
IceInternal::BasicStream::write(const string& v)
{
Int len = static_cast<Int>(v.size());
writeSize(len);
if(len > 0)
{
Container::size_type pos = b.size();
resize(pos + len);
memcpy(&b[pos], v.c_str(), len);
}
}

void
IceInternal::BasicStream::read(string& v)
{
Int len;
readSize(len);
if(b.end() - i < len)
{
throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
}
if(len > 0)
{
v.assign(reinterpret_cast<const char*>(&(*i)), len);
i += len;
}
else
{
v.clear();
}
}

basicstream.cs:
public virtual void writeString(string v)
{
if(v == null || v.Length == 0)
{
writeSize(0);
return;
}
try
{
byte[] arr = utf8.GetBytes(v);
writeSize(arr.Length);
expand(arr.Length);
_buf.put(arr);
}
catch(Exception)
{
Debug.Assert(false);
}
}

public virtual string readString()
{
int len = readSize();

if(len == 0)
{
return "";
}

try
{
if(_stringBytes == null || len > _stringBytes.Length)
{
_stringBytes = new byte[len];
}
_buf.get(_stringBytes, 0, len);
return utf8.GetString(_stringBytes, 0, len);
}
catch(InvalidOperationException ex)
{
throw new Ice.UnmarshalOutOfBoundsException(ex);
}
catch(System.ArgumentException ex)
{
throw new Ice.MarshalException("Invalid UTF8 string", ex);
}
catch(Exception)
{
Debug.Assert(false);
return "";
}
}

So it seems the implementation of cs support UTF8,and C++ not support UTF8 but MBCS ??
When I use System.Text.Encoding.Default intead of UTF8Encoding in cs client,the server
can receive and print the string correctly.


my platform:
the Ice/IceCS version is 1.5.1, win 2000/vs.net 2003(7.1.3091)/.net 1.1(1.1.4322)

slice:
interface IPrinter
{
void Print(string s);
};

The Server:

class PrinterImpl : public IPrinter
{
public:
PrinterImpl(void);
virtual ~PrinterImpl(void);

virtual void Print(const ::std::string&, const ::Ice::Current& current);
};
PrinterImpl::PrinterImpl(void)
{
}

PrinterImpl::~PrinterImpl(void)
{
}

void PrinterImpl::Print(const ::std::string& s, const ::Ice::Current& current)
{
cout<<s<<endl;
}

Last edited by ChaosXu : 10-28-2004 at 05:30 AM.
Reply With Quote