[Mono-bugs] [Bug 55450][Maj] New - Mono marshals unicode char[] without an implicit [Out]

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Wed, 10 Mar 2004 22:06:13 -0500 (EST)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by swbrown@ucsd.edu.

http://bugzilla.ximian.com/show_bug.cgi?id=55450

--- shadow/55450	2004-03-10 22:06:13.000000000 -0500
+++ shadow/55450.tmp.27836	2004-03-10 22:06:13.000000000 -0500
@@ -0,0 +1,80 @@
+Bug#: 55450
+Product: Mono: Runtime
+Version: unspecified
+OS: All
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Major
+Component: misc
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: swbrown@ucsd.edu               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Mono marshals unicode char[] without an implicit [Out]
+
+Mono (0.30.2) marshals unicode char[] in such a way that changes made to 
+the array by native code are lost unless you explicitly specify [Out].  
+Microsoft's implementation treats it as implicitly [Out].
+
+I'm not really sure who's wrong here, but there's definately a 
+discrepancy.  It used to work like Microsoft's in Mono, probably around 
+0.26.  It's also rather odd that Mono treats byte[] as implicitly [Out], 
+but not char[].  Here's a simple example to show the difference between 
+Mono and Microsoft:
+
+With Microsoft's .NET ("libc" => "msvcrt"):
+
+char[] marshalling, Before: This is a test, Result: This is a test
+byte[] marshalling, Before: This is a test, Result: This is a test
+
+But with Mono, you'll get (unless you add [Out]):
+
+char[] marshalling, Before: This is a test, Result: 
+byte[] marshalling, Before: This is a test, Result: This is a test
+
+
+
+using System;
+using System.Runtime.InteropServices;
+
+class Test {
+
+  [DllImport("libc", CharSet = CharSet.Unicode)]
+  public static extern IntPtr memmove(char[] dest, IntPtr src, int size);
+
+  [DllImport("libc", CharSet = CharSet.Unicode)]
+  public static extern IntPtr memmove(byte[] dest, IntPtr src, int size);
+
+  public static void Main(string[] args) {
+
+    // Put a unicode string in unmanaged memory.
+    string unicodeString = "This is a test";
+    IntPtr unmanagedUnicodeString = Marshal.StringToHGlobalUni
+(unicodeString);
+
+
+    // Copy it into a marshalled char[] buffer.
+    char[] charBuffer = new char[unicodeString.Length];
+    memmove(charBuffer, unmanagedUnicodeString, 2 * unicodeString.Length);
+
+    // Display it as a unicode string.
+    string charString = new string(charBuffer);
+    System.Console.WriteLine("char[] marshalling, Before: {0}, Result: 
+{1}", unicodeString, charString);
+
+
+    // Copy it into a marshalled byte[] buffer.
+    byte[] byteBuffer = new byte[2 * unicodeString.Length];
+    memmove(byteBuffer, unmanagedUnicodeString, 2 * unicodeString.Length);
+
+    // Display it as a unicode string.
+    string byteString = new string(System.Text.Encoding.Unicode.GetChars
+(byteBuffer));
+    System.Console.WriteLine("byte[] marshalling, Before: {0}, Result: 
+{1}", unicodeString, byteString);
+  }
+}