Author: zoltan
Date: 2005-06-03 15:05:56 -0400 (Fri, 03 Jun 2005)
New Revision: 45380

Modified:
   trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog
   trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
   trunk/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs
Log:
2005-06-03  Zoltan Varga  <[EMAIL PROTECTED]>

        * MethodBuilder.cs CustomAttributeBuilder.cs: Rework DllImportAttribute
        decoding to improve compatibility with MS.NET.


Modified: trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog     2005-06-03 
18:30:24 UTC (rev 45379)
+++ trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog     2005-06-03 
19:05:56 UTC (rev 45380)
@@ -1,5 +1,8 @@
 2005-06-03  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * MethodBuilder.cs CustomAttributeBuilder.cs: Rework DllImportAttribute
+       decoding to improve compatibility with MS.NET.
+       
        * MethodBuilder.cs (SetCustomAttribute): Set PinvokeImpl attribute if
        a DllImportAttribute is present.
 

Modified: 
trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
===================================================================
--- trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs     
2005-06-03 18:30:24 UTC (rev 45379)
+++ trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs     
2005-06-03 19:05:56 UTC (rev 45380)
@@ -311,11 +311,20 @@
                        }
                }
 
-               internal static object decode_cattr (CustomAttributeBuilder 
customBuilder) {
+               internal struct CustomAttributeInfo {
+                       public ConstructorInfo ctor;
+                       public object[] ctorArgs;
+                       public string[] namedParamNames;
+                       public object[] namedParamValues;
+               }
+
+               internal static CustomAttributeInfo decode_cattr 
(CustomAttributeBuilder customBuilder) {
                        byte[] data = customBuilder.Data;
                        ConstructorInfo ctor = customBuilder.Ctor;
                        int pos = 0;
 
+                       CustomAttributeInfo info = new CustomAttributeInfo ();
+
                        // Prolog
                        if (data.Length < 2)
                                throw new Exception ();
@@ -324,15 +333,16 @@
                        pos = 2;
 
                        ParameterInfo [] pi = ctor.GetParameters ();
-                       object[] ctorArgs = new object [pi.Length];
+                       info.ctor = ctor;
+                       info.ctorArgs = new object [pi.Length];
                        for (int i = 0; i < pi.Length; ++i)
-                               ctorArgs [i] = decode_cattr_value (pi 
[i].ParameterType, data, pos, out pos);
+                               info.ctorArgs [i] = decode_cattr_value (pi 
[i].ParameterType, data, pos, out pos);
 
-                       object res = ctor.Invoke (ctorArgs);
-
                        int num_named = data [pos] + (data [pos + 1] * 256);
                        pos += 2;
 
+                       info.namedParamNames = new string [num_named];
+                       info.namedParamValues = new object [num_named];
                        for (int i = 0; i < num_named; ++i) {
                                int named_type = data [pos++];
                                int data_type = data [pos++];
@@ -346,6 +356,7 @@
 
                                int len = decode_len (data, pos, out pos);
                                string name = string_from_bytes (data, pos, 
len);
+                               info.namedParamNames [i] = name;
                                pos += len;
 
                                if (named_type == 0x53) {
@@ -360,14 +371,14 @@
                                                val = Enum.ToObject (enumType, 
val);
                                        }
 
-                                       fi.SetValue (res, val);
+                                       info.namedParamValues [i] = val;
                                }
                                else
                                        // FIXME:
                                        throw new Exception ();
                        }
 
-                       return res;
+                       return info;
                }
        }
 }

Modified: trunk/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs
===================================================================
--- trunk/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs      
2005-06-03 18:30:24 UTC (rev 45379)
+++ trunk/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs      
2005-06-03 19:05:56 UTC (rev 45380)
@@ -302,23 +302,50 @@
                                return;
                        }
                        if (attrname == 
"System.Runtime.InteropServices.DllImportAttribute") {
-                               DllImportAttribute attr = 
(DllImportAttribute)CustomAttributeBuilder.decode_cattr (customBuilder);
-                               pi_dll = attr.Value;
-                               pi_entry = attr.EntryPoint;
-                               if (attr.CallingConvention == 0)
-                                       native_cc = 
System.Runtime.InteropServices.CallingConvention.Winapi;
-                               else
-                                       native_cc = attr.CallingConvention;
-                               charset = attr.CharSet;
-                               ExactSpelling = attr.ExactSpelling;
-                               if (attr.PreserveSig)
-                                       iattrs |= 
MethodImplAttributes.PreserveSig;
-                               SetLastError = attr.SetLastError;
+                               CustomAttributeBuilder.CustomAttributeInfo attr 
= CustomAttributeBuilder.decode_cattr (customBuilder);
+                               bool preserveSig = true;
+
+                               /*
+                                * It would be easier to construct a 
DllImportAttribute from
+                                * the custom attribute builder, but the 
DllImportAttribute 
+                                * does not contain all the information 
required here, ie.
+                                * - some parameters, like BestFitMapping has 
three values
+                                *   ("on", "off", "missing"), but 
DllImportAttribute only
+                                *   contains two (on/off).
+                                * - PreserveSig is true by default, while it 
is false by
+                                *   default in DllImportAttribute.
+                                */
+
+                               pi_dll = (string)attr.ctorArgs [0];
+                               native_cc = 
System.Runtime.InteropServices.CallingConvention.Winapi;
+
+                               for (int i = 0; i < 
attr.namedParamNames.Length; ++i) {
+                                       string name = attr.namedParamNames [i];
+                                       object value = attr.namedParamValues 
[i];
+
+                                       if (name == "CallingConvention")
+                                               native_cc = 
(CallingConvention)value;
+                                       else if (name == "CharSet")
+                                               charset = (CharSet)value;
+                                       else if (name == "EntryPoint")
+                                               pi_entry = (string)value;
+                                       else if (name == "ExactSpelling")
+                                               ExactSpelling = (bool)value;
+                                       else if (name == "SetLastError")
+                                               SetLastError = (bool)value;
+                                       else if (name == "PreserveSig")
+                                               preserveSig = (bool)value;
 #if NET_1_1
-                               BestFitMapping = attr.BestFitMapping;
-                               ThrowOnUnmappableChar = 
attr.ThrowOnUnmappableChar;
+                                       else if (name == "BestFitMapping")
+                                               BestFitMapping = (bool)value;
+                                       else if (name == 
"ThrowOnUnmappableChar")
+                                               ThrowOnUnmappableChar = 
(bool)value;
 #endif
+                               }
+
                                attrs |= MethodAttributes.PinvokeImpl;
+                               if (preserveSig)
+                                       iattrs |= 
MethodImplAttributes.PreserveSig;
                                return;
                        }
                        if (cattrs != null) {

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to