Hi,

The attached patch fixes some problems we are seeing with marshaling
bools and IDspatch types in Native code.

I can split the patch separating the bool changes form the dispatch
changes if needed.  I would like to apply this to the 2.4 branch as
well.

-bill

2009-02-12  Bill Holmes  <billholme...@gmail.com>

        * object-internals.h : Fixing a typo in the
          MonoReflectionComVisibleAttribute struct.

        * marshal.c (cominterop_com_visible): Check the implemented
          interfaces for ComImport.

        * marshal.c (cominterop_get_native_wrapper_adjusted): For COM calls
          assume that bools should be treated as VARIANTBOOLs.

        * marshal.c (emit_marshal_boolean): Adding cases for
          MARSHAL_ACTION_MANAGED_CONV_IN and MARSHAL_ACTION_MANAGED_CONV_OUT.

        * marshal.c (mono_marshal_emit_managed_wrapper): Adding calls to
          emit_marshal MARSHAL_ACTION_MANAGED_CONV_IN and OUT for bools.

        * marshal.c (cominterop_get_ccw): For COM calls assume that bools
          should be treated as VARIANTBOOLs.    

        Code is contributed under MIT/X11 license.
Index: mono/metadata/ChangeLog
===================================================================
--- mono/metadata/ChangeLog	(revision 126646)
+++ mono/metadata/ChangeLog	(working copy)
@@ -1,3 +1,25 @@
+2009-02-12  Bill Holmes  <billholme...@gmail.com>
+
+	* object-internals.h : Fixing a typo in the 
+	  MonoReflectionComVisibleAttribute struct.
+
+	* marshal.c (cominterop_com_visible): Check the implemented 
+	  interfaces for ComImport.
+
+	* marshal.c (cominterop_get_native_wrapper_adjusted): For COM calls 
+	  assume that bools should be treated as VARIANTBOOLs.
+
+	* marshal.c (emit_marshal_boolean): Adding cases for 
+	  MARSHAL_ACTION_MANAGED_CONV_IN and MARSHAL_ACTION_MANAGED_CONV_OUT.
+
+	* marshal.c (mono_marshal_emit_managed_wrapper): Adding calls to 
+	  emit_marshal MARSHAL_ACTION_MANAGED_CONV_IN and OUT for bools.
+
+	* marshal.c (cominterop_get_ccw): For COM calls assume that bools
+	  should be treated as VARIANTBOOLs.	
+
+	Code is contributed under MIT/X11 license.
+
 2009-02-11  Mark Probst  <mark.pro...@gmail.com>
 
 	* class.c, class-internals.h: mono_method_get_context_general()
Index: mono/metadata/marshal.c
===================================================================
--- mono/metadata/marshal.c	(revision 126646)
+++ mono/metadata/marshal.c	(working copy)
@@ -495,24 +495,39 @@
 {
 	static MonoClass *ComVisibleAttribute = NULL;
 	MonoCustomAttrInfo *cinfo;
+	GPtrArray *ifaces;
+	MonoBoolean visible = 0;
 
 	/* Handle the ComVisibleAttribute */
 	if (!ComVisibleAttribute)
 		ComVisibleAttribute = mono_class_from_name (mono_defaults.corlib, "System.Runtime.InteropServices", "ComVisibleAttribute");
 
-	cinfo = mono_custom_attrs_from_class (klass);	
+	cinfo = mono_custom_attrs_from_class (klass);
 	if (cinfo) {
 		MonoReflectionComVisibleAttribute *attr = (MonoReflectionComVisibleAttribute*)mono_custom_attrs_get_attr (cinfo, ComVisibleAttribute);
 
-		if (!attr)
-			return FALSE;
+		if (attr)
+			visible = attr->visible;
 		if (!cinfo->cached)
 			mono_custom_attrs_free (cinfo);
-
-		if (attr->visible)
+		if (visible)
 			return TRUE;
 	}
-	return FALSE;
+
+	ifaces = mono_class_get_implemented_interfaces (klass);
+	if (ifaces) {
+		int i;
+		for (i = 0; i < ifaces->len; ++i) {
+			MonoClass *ic = NULL;
+			ic = g_ptr_array_index (ifaces, i);
+			if (MONO_CLASS_IS_IMPORT (ic))
+				visible = TRUE;
+
+		}
+		g_ptr_array_free (ifaces, TRUE);
+	}
+	return visible;
+
 }
 
 static void cominterop_raise_hr_exception (int hr)
@@ -3296,6 +3311,10 @@
 				mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
 				mspecs[mspec_index]->native = MONO_NATIVE_INTERFACE;
 			}
+			else if (sig_native->params[i]->type == MONO_NATIVE_BOOLEAN) {
+				mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
+				mspecs[mspec_index]->native = MONO_NATIVE_VARIANTBOOL;
+			}
 		}
 	}
 
@@ -3315,6 +3334,10 @@
 				mspecs[0] = g_new0 (MonoMarshalSpec, 1);
 				mspecs[0]->native = MONO_NATIVE_INTERFACE;
 			}
+			else if (sig->ret->type == MONO_NATIVE_BOOLEAN) {
+				mspecs[0] = g_new0 (MonoMarshalSpec, 1);
+				mspecs[0]->native = MONO_NATIVE_VARIANTBOOL;
+			}
 		}
 	}
 
@@ -8489,6 +8512,68 @@
 		mono_mb_emit_stloc (mb, 3);
 		break;
 
+	case MARSHAL_ACTION_MANAGED_CONV_IN: {
+		gint variant_bool = 0;
+		guint8 ldop = CEE_LDIND_I4;
+		if (!t->byref)
+			break;
+
+		conv_arg = mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
+
+		*conv_arg_type = &mono_defaults.int32_class->byval_arg;
+
+		if (spec) {
+			switch (spec->native) {
+			case MONO_NATIVE_I1:
+			case MONO_NATIVE_U1:
+				*conv_arg_type = &mono_defaults.byte_class->this_arg;
+				ldop = CEE_LDIND_I1;
+				break;
+			case MONO_NATIVE_VARIANTBOOL:
+				*conv_arg_type = &mono_defaults.int16_class->this_arg;
+				variant_bool = 1;
+				ldop = CEE_LDIND_I2;
+				break;
+			default:
+				g_warning ("marshalling bool as native type %x is currently not supported", spec->native);
+			}
+		}
+		
+		mono_mb_emit_ldarg (mb, argnum);
+		mono_mb_emit_byte (mb, ldop);	
+
+		if (variant_bool)
+			mono_mb_emit_byte (mb, CEE_NEG);
+		mono_mb_emit_stloc (mb, conv_arg);
+		break;
+	}
+
+	case MARSHAL_ACTION_MANAGED_CONV_OUT: {
+		guint8 stop = CEE_STIND_I4;
+		if (!t->byref)
+			break;
+		if (spec) {
+			switch (spec->native) {
+			case MONO_NATIVE_I1:
+			case MONO_NATIVE_U1:
+				stop = CEE_STIND_I1;
+				break;
+			case MONO_NATIVE_VARIANTBOOL:
+				stop = CEE_STIND_I2;
+				break;
+			default:
+				break;
+			}
+		}
+
+		mono_mb_emit_ldarg (mb, argnum);
+		mono_mb_emit_ldloc (mb, conv_arg);
+		if (spec != NULL && spec->native == MONO_NATIVE_VARIANTBOOL)
+			mono_mb_emit_byte (mb, CEE_NEG);
+		mono_mb_emit_byte (mb, stop);
+		break;
+	}
+
 	default:
 		g_assert_not_reached ();
 	}
@@ -9113,6 +9198,7 @@
 		case MONO_TYPE_ARRAY:
 		case MONO_TYPE_SZARRAY:
 		case MONO_TYPE_STRING:
+		case MONO_TYPE_BOOLEAN:
 			tmp_locals [i] = emit_marshal (m, i, sig->params [i], mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN);
 
 			break;
@@ -9207,6 +9293,7 @@
 			case MONO_TYPE_VALUETYPE:
 			case MONO_TYPE_OBJECT:
 			case MONO_TYPE_STRING:
+			case MONO_TYPE_BOOLEAN:
 				emit_marshal (m, i, t, mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
 				break;
 			}
@@ -12191,6 +12278,10 @@
 						mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
 						mspecs[mspec_index]->native = MONO_NATIVE_INTERFACE;
 					}
+					else if (sig_adjusted->params[param_index]->type == MONO_NATIVE_BOOLEAN) {
+						mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
+						mspecs[mspec_index]->native = MONO_NATIVE_VARIANTBOOL;
+					}
 				}
 			}
 
@@ -12212,6 +12303,10 @@
 						mspecs[0] = g_new0 (MonoMarshalSpec, 1);
 						mspecs[0]->native = MONO_NATIVE_INTERFACE;
 					}
+					else if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_NATIVE_BOOLEAN) {
+						mspecs[0] = g_new0 (MonoMarshalSpec, 1);
+						mspecs[0]->native = MONO_NATIVE_VARIANTBOOL;
+					}
 				}
 
 				mspecs [sig_adjusted->param_count] = mspecs [0];
Index: mono/metadata/object-internals.h
===================================================================
--- mono/metadata/object-internals.h	(revision 126646)
+++ mono/metadata/object-internals.h	(working copy)
@@ -1089,7 +1089,7 @@
 
 typedef struct {
 	MonoObject object;
-	MonoBoolean *visible;
+	MonoBoolean visible;
 } MonoReflectionComVisibleAttribute;
 
 enum {
@@ -1279,3 +1279,4 @@
 
 #endif /* __MONO_OBJECT_INTERNALS_H__ */
 
+
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to