[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);
+ }
+}