<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Trouble with utf-16 marshaling</TITLE>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.6000.16481" name=GENERATOR></HEAD>
<BODY>
<DIV dir=ltr align=left><FONT color=#0000ff>
<DIV dir=ltr align=left><SPAN class=687455022-29062007><FONT face=Arial 
size=2>If the string argument is mutable then I believe one should use a 
StringBuilder -- with its capacity set, and that length passed to the native 
function too.&nbsp; And if the native method writes more chars than allocated 
then the heap will be corrupted. :-(</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=687455022-29062007><FONT face=Arial 
size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=687455022-29062007><FONT face=Arial 
size=2>So with native method:</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=687455022-29062007><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp; void my_function(unsigned short* myArg, int maxLen); 
</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=687455022-29062007><FONT face=Arial 
size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=687455022-29062007><FONT face=Arial 
size=2>Do </FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=687455022-29062007>
<P><FONT face=Arial><FONT size=2><SPAN 
class=687455022-29062007>&nbsp;&nbsp;&nbsp; </SPAN>[DllImport("myCLib"<SPAN 
class=687455022-29062007>, 
CharSet=CharSet.Unicode</SPAN>)]<BR></FONT></FONT></SPAN><SPAN 
class=687455022-29062007><FONT face=Arial><FONT size=2><SPAN 
class=718271123-29062007>&nbsp;&nbsp;&nbsp; // I think &lt;CharSet&gt; on that 
attr is enough, no need for MarshalAs on the param...<BR>&nbsp;&nbsp;&nbsp; 
p</SPAN>ublic static extern void my_function(<SPAN 
class=687455022-29062007>S</SPAN>tring<SPAN 
class=687455022-29062007>Builder</SPAN> myArg<SPAN class=687455022-29062007>, 
int maxLength</SPAN>); <BR></FONT></FONT><SPAN class=687455022-29062007><FONT 
face=Arial size=2>...<BR></FONT></SPAN></SPAN><SPAN 
class=687455022-29062007><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; 
StringBuilder bldr = new StringBuilder(256);<BR>&nbsp;&nbsp;&nbsp; 
NativeMethods.my_function(bldr, bldr.Capacity);</FONT></SPAN></P></DIV>
<DIV dir=ltr align=left>
<P><SPAN class=687455022-29062007><FONT face=Arial size=2>See a similar sample 
at </FONT><A 
href="http://msdn2.microsoft.com/en-us/library/x3txb6xc(vs.80).aspx"><FONT 
face=Arial 
size=2>http://msdn2.microsoft.com/en-us/library/x3txb6xc(vs.80).aspx</FONT></A><FONT 
face=Arial size=2>, and reference material at </FONT><A 
href="http://msdn2.microsoft.com/en-us/library/s9ts558h(VS.80).aspx"><FONT 
face=Arial 
size=2>http://msdn2.microsoft.com/en-us/library/s9ts558h(VS.80).aspx</FONT></A><FONT 
face=Arial size=2>&nbsp;etc.</FONT></SPAN></P>
<P><FONT face=Arial><FONT size=2><SPAN class=687455022-29062007>Unless I'm much 
confused it shouldn't work (at least isn't guaranteed to) on MSFT either: 
</SPAN><SPAN class=687455022-29062007>"Platform invoke copies string arguments, 
converting from the .NET Framework format (Unicode) to the platform unmanaged 
format. Strings are immutable and are not copied back from unmanaged memory to 
managed memory when the call returns."</SPAN></FONT></FONT></P>
<P><SPAN class=687455022-29062007><FONT face=Arial size=2>I suppose since it is 
Unicode on both sides the MSFT CLR skips the copy and just passed the address of 
the String's content.&nbsp; Whereas Mono doesn't have that optimisation 
perhaps.</FONT></SPAN></P>
<P><SPAN class=687455022-29062007><FONT face=Arial size=2>Does that solve it, or 
is something else the problem?</FONT></SPAN></P>
<P><SPAN class=687455022-29062007><FONT face=Arial 
size=2>Andy</FONT></SPAN></P></DIV></FONT></DIV><BR>
<BLOCKQUOTE dir=ltr 
style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #0000ff 2px solid; MARGIN-RIGHT: 0px">
  <DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left>
  <HR tabIndex=-1>
  <FONT face=Tahoma size=2><B>From:</B> mono-list-bounces@lists.ximian.com 
  [mailto:mono-list-bounces@lists.ximian.com] <B>On Behalf Of </B>Maser, 
  Dan<BR><B>Sent:</B> 29 June 2007 23:23<BR><B>To:</B> Maser, Dan; 
  mono-list@lists.ximian.com<BR><B>Subject:</B> Re: [Mono-list] Trouble with 
  utf-16 marshaling<BR></FONT><BR></DIV>
  <DIV></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp; I have debugged this some more, and 
  found this.&nbsp; (I'm not yet sure how to convert this information into 
  something actionable).</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>I was browsing some of the mono source code and found 
  this function (and its sisters):</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MonoString* 
  mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 
  len);</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>which seem to be the function(s) that initialize 
  internal C# strings from C data.&nbsp; This one in particular appears to be 
  invoked when internal C# strings are created from UTF-16 "C" data.&nbsp;&nbsp; 
  I hacked in a simple loop that printf'd the hex values of the UTF-16 data (the 
  'text' parameter).</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp; What I see in my console window is 
  interesting.&nbsp; (After a bunch of unrelated stuff) I see my C library 
  returning a UTF-16 string that gets correctly interpreted 
  as&nbsp;MonoString:</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp;&nbsp; DBG: invocation of 
  mono_string_new_utf16 with data:</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  002f&nbsp; 00<STRONG>68</STRONG>&nbsp; 006f&nbsp; 00<STRONG>6d</STRONG>&nbsp; 
  0065&nbsp; 00<STRONG>2f</STRONG>&nbsp; 0064 &nbsp;00<STRONG>61</STRONG> 
  &nbsp;006e &nbsp;00<STRONG>6d</STRONG> &nbsp;002f&nbsp; 00<STRONG>69</STRONG> 
  &nbsp;006e&nbsp; 00<STRONG>74</STRONG> ...</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>which is the correct string.&nbsp; The next thing I 
  see in the console window is this:</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial size=2><SPAN 
class=329470722-29062007>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp;&nbsp; DBG: invocation of 
  mono_string_new_utf16 with data:</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <STRONG>68</STRONG>2f&nbsp; <STRONG>6d</STRONG>6f &nbsp;<STRONG>2f</STRONG>65 
  &nbsp;<STRONG>61</STRONG>64 &nbsp;<STRONG>6d</STRONG>6e 
  &nbsp;<STRONG>69</STRONG>2f&nbsp; <STRONG>74</STRONG>6e''</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>Notice that this second data is similiar to the first 
  where each 2-bytes in the second string is the corresponding *4* bytes of the 
  first string and re-ordered as if there were some endian issue.&nbsp; Clearly 
  this second string is supposed to be the same as the first string but it's 
  been damaged by some translation process.</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007></SPAN></FONT>&nbsp;</DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp; Does that information mean anything to 
  anyone?&nbsp;&nbsp; As always, thanks for any help.</SPAN></FONT></DIV>
  <DIV dir=ltr align=left><FONT face=Arial color=#0000ff size=2><SPAN 
  class=329470722-29062007>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dan 
  Maser.</SPAN></FONT></SPAN></FONT></DIV></DIV><FONT face=Arial color=#0000ff 
  size=2></FONT><BR>
  <DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left>
  <HR tabIndex=-1>
  <FONT face=Tahoma size=2><B>From:</B> Maser, Dan <BR><B>Sent:</B> Friday, June 
  29, 2007 1:10 PM<BR><B>To:</B> Maser, Dan; 
  'mono-list@lists.ximian.com'<BR><B>Subject:</B> RE: [Mono-list] Trouble with 
  utf-16 marshaling<BR></FONT><BR></DIV>
  <DIV></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>&nbsp;&nbsp; Furthermore, I see in the mono source code 
  that there is a test function in the 
  mono/mono/tests/libtest.c</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>STDCALL unsigned short*</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>test_lpwstr_marshal (unsigned short* chars, long 
  length)</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>{</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>...</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>}</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
  <DIV dir=ltr align=left><SPAN class=090580718-29062007><FONT face=Arial 
  color=#0000ff size=2>&nbsp;&nbsp; Which is basically the same thing I'm doing; 
  further indicating that this should work.</FONT></SPAN></DIV><BR>
  <DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left>
  <HR tabIndex=-1>
  <FONT face=Tahoma size=2><B>From:</B> mono-list-bounces@lists.ximian.com 
  [mailto:mono-list-bounces@lists.ximian.com] <B>On Behalf Of </B>Maser, 
  Dan<BR><B>Sent:</B> Friday, June 29, 2007 9:13 AM<BR><B>To:</B> 
  mono-list@lists.ximian.com<BR><B>Subject:</B> [Mono-list] Trouble with utf-16 
  marshaling<BR></FONT><BR></DIV>
  <DIV></DIV><!-- Converted from text/rtf format --><BR>
  <P><FONT face=Arial size=2>&nbsp;&nbsp; My situation is this:&nbsp; I've got a 
  C library that has a lot of UTF-16 inputs and outputs.&nbsp; The C type is 
  always "unsigned short*" or "const unsigned short*" (because clearly wchar_t* 
  isn't portable because it's 4 bytes on linux).&nbsp;&nbsp; All of my C# code 
  has the "[MarshalAs(UnsignedType.LPWStr)]" attribute specified.</FONT></P>
  <P><FONT face=Arial size=2>&nbsp;&nbsp; It works properly in windows with MS 
  .NET, but doesn't work for me in linux with mono.&nbsp;&nbsp; I've verified in 
  gdb that the C library is returning the correct string, but immediately after 
  the C dll returns and mono does the LPWStr marshaling the string is total 
  garbage characters.&nbsp;&nbsp; I am under the impression from previous posts 
  that 2-byte UTF-16 should marshal properly to mono with the LPWStr 
  attribute.&nbsp; In fact it looks like some of the gdiplus calls use that same 
  thing and work&#8230; any ideas what I can check on because mine doesn't?</FONT></P>
  <P><FONT face=Arial size=2>&nbsp;&nbsp; For more clarification my C library 
  has a function signature like this:</FONT> </P>
  <P><FONT face=Arial size=2>void my_function(unsigned short* myArg);</FONT> 
</P>
  <P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; And my C# code looks like 
  this:</FONT> </P><BR>
  <P><FONT face=Arial size=2>[DllImport("myCLib")]</FONT> <BR><FONT face=Arial 
  size=2>public static extern void my_function([MarshalAs(UnmanagedType.LPWStr)] 
  string myArg);</FONT> </P>
  <P><FONT face=Arial size=2>&nbsp;&nbsp; Thanks in advance for any ideas on 
  what to check!</FONT> <BR><FONT face=Arial 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dan Maser</FONT> 
</P></BLOCKQUOTE></BODY></HTML>