[Mono-bugs] [Bug 58881][Maj] New - marshalling of struct params to functions passed as unmanaged delegates broken

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Sun, 23 May 2004 18:22:54 -0400 (EDT)


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 vladimir@pobox.com.

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

--- shadow/58881	2004-05-23 18:22:53.000000000 -0400
+++ shadow/58881.tmp.26234	2004-05-23 18:22:53.000000000 -0400
@@ -0,0 +1,97 @@
+Bug#: 58881
+Product: Mono: Runtime
+Version: unspecified
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Major
+Component: misc
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: vladimir@pobox.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: marshalling of struct params to functions passed as unmanaged delegates broken
+
+Given two code files, t37.c and t37.cs:
+
+=== t37.cs ===
+#include <stdio.h>
+ 
+typedef struct {
+    int i;
+    int j;
+} SomeStruct;
+ 
+typedef void (*SomeStructCB) (SomeStruct *ss);
+ 
+void
+doit (SomeStructCB sscb)
+{
+    SomeStruct ss;
+    ss.i = ss.j = 0;
+    printf ("unmanaged &ss: 0x%08x\n", &ss);
+    sscb (&ss);
+    printf ("unmanaged ss.i: %d ss.j: %d\n", ss.i, ss.j);
+}
+=== end ===
+
+=== t37.cs ===
+using System;
+using System.Runtime.InteropServices;
+ 
+public class Driver {
+    [StructLayout(LayoutKind.Sequential)]
+    public struct SomeStruct {
+        public int i;
+        public int j;
+    }
+ 
+ 
+    [DllImport("t37.so")]
+    static extern void doit (cbdelegate smcb);
+ 
+#if true
+    delegate void cbdelegate (ref SomeStruct ss);
+    public static void sscb (ref SomeStruct ss) {
+        unsafe {
+            int *p = (int *) &ss;
+            Console.WriteLine ("p = 0x{0}, *p = {1}", ((int)
+p).ToString("x"), *p);
+        }
+        ss.i = 10;
+        ss.j = 20;
+    }
+#else
+    delegate void cbdelegate (IntPtr sptr);
+    public static void sscb (IntPtr sptr) {
+        Console.WriteLine ("sptr: {0}", ((int) sptr).ToString("x"));
+    }
+#endif
+ 
+    public static void Main () {
+        doit (new cbdelegate(sscb));
+    }
+}
+=== end ===
+
+If the code is built as is, with the #if true, the output is:
+unmanaged &ss: 0xf68d583c
+p = 0xf68d580c, *p = 0
+unmanaged ss.i: 0 ss.j: 0
+
+Note that the value for the unmanaged &ss is different from p (which is &ss
+in managed code -- technically, that should only be allowed within a
+fixed(), but using fixed() gives the same results).  Also the setting of
+i/j has no effect on the struct passed in.
+
+If the #if true is changed to #if false (where just an IntPtr is received
+by the delegate), the resulting addresses match up:
+
+&ss: 0xf68b783c
+sptr: f68b783c
+
+Is this a bug in unmanaged -> managed struct ref marshalling?