[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?