2
0
Эх сурвалжийг харах

2005-02-15 Zoltan Varga <[email protected]>

	* marshal.c (mono_ftnptr_to_delegate): If the delegate has the 
	UnmanagedFunctionPointerAttribute, use it for determining calling convention
	etc. Fixes #71471.

	* reflection.c (mono_custom_attrs_get_attr): New helper function.

	* object-internals.h: Add MonoReflectionUnmanagedFunctionPointerAttribute.

svn path=/trunk/mono/; revision=40710
Zoltan Varga 21 жил өмнө
parent
commit
c2e03a6adf

+ 9 - 0
mono/metadata/ChangeLog

@@ -1,3 +1,12 @@
+2005-02-15  Zoltan Varga  <[email protected]>
+
+	* marshal.c (mono_ftnptr_to_delegate): If the delegate has the 
+	UnmanagedFunctionPointerAttribute, use it for determining calling convention
+	etc. Fixes #71471.
+
+	* reflection.c (mono_custom_attrs_get_attr): New helper function.
+
+	* object-internals.h: Add MonoReflectionUnmanagedFunctionPointerAttribute.
 
 Tue Feb 15 18:03:41 CET 2005 Paolo Molaro <[email protected]>
 

+ 28 - 8
mono/metadata/marshal.c

@@ -280,18 +280,41 @@ mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
 	LeaveCriticalSection (&marshal_mutex);
 	if (d == NULL) {
 		/* This is a native function, so construct a delegate for it */
+		static MonoClass *UnmanagedFunctionPointerAttribute;
 		MonoMethodSignature *sig;
 		MonoMethod *wrapper;
 		MonoMarshalSpec **mspecs;
+		MonoCustomAttrInfo *cinfo;
+		MonoReflectionUnmanagedFunctionPointerAttribute *attr;
 		MonoMethod *invoke = mono_get_delegate_invoke (klass);
+		MonoMethodPInvoke piinfo;
 		int i;
 
+		memset (&piinfo, 0, sizeof (piinfo));
+		if (!UnmanagedFunctionPointerAttribute)
+			UnmanagedFunctionPointerAttribute = mono_class_from_name (mono_defaults.corlib, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
+
+		/* The attribute is only available in Net 2.0 */
+		if (UnmanagedFunctionPointerAttribute) {
+			/* 
+			 * The pinvoke attributes are stored in a real custom attribute so we have to
+			 * construct it.
+			 */
+			cinfo = mono_custom_attrs_from_class (klass);
+			attr = (MonoReflectionUnmanagedFunctionPointerAttribute*)mono_custom_attrs_get_attr (cinfo, UnmanagedFunctionPointerAttribute);
+			if (attr) {
+				piinfo.piflags = (attr->call_conv << 8) | (attr->charset ? (attr->charset - 1) * 2 : 1) | attr->set_last_error;
+			}
+			if (!cinfo->cached)
+				mono_custom_attrs_free (cinfo);
+		}
+
 		mspecs = g_new0 (MonoMarshalSpec*, mono_method_signature (invoke)->param_count + 1);
 		mono_method_get_marshal_info (invoke, mspecs);
 		sig = mono_metadata_signature_dup (mono_method_signature (invoke));
 		sig->hasthis = 0;
 
-		wrapper = mono_marshal_get_native_func_wrapper (sig, mspecs, ftn);
+		wrapper = mono_marshal_get_native_func_wrapper (sig, &piinfo, mspecs, ftn);
 
 		for (i = mono_method_signature (invoke)->param_count; i >= 0; i--)
 			if (mspecs [i])
@@ -6111,10 +6134,11 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
  * wrapper.
  */
 MonoMethod *
-mono_marshal_get_native_func_wrapper (MonoMethodSignature *sig, MonoMarshalSpec **mspecs, gpointer func)
+mono_marshal_get_native_func_wrapper (MonoMethodSignature *sig, 
+									  MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func)
 {
 	MonoMethodSignature *csig;
-	MonoMethodPInvoke piinfo;
+
 	MonoMethodBuilder *mb;
 	MonoMethod *res;
 	GHashTable *cache;
@@ -6124,15 +6148,11 @@ mono_marshal_get_native_func_wrapper (MonoMethodSignature *sig, MonoMarshalSpec
 	if ((res = mono_marshal_find_in_cache (cache, func)))
 		return res;
 
-
 	name = g_strdup_printf ("wrapper_native_%p", func);
 	mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
 	mb->method->save_lmf = 1;
 
-	/* FIXME: Collect piinfo */
-	memset (&piinfo, 0, sizeof (piinfo));
-
-	mono_marshal_emit_native_wrapper (mb, sig, &piinfo, mspecs, func);
+	mono_marshal_emit_native_wrapper (mb, sig, piinfo, mspecs, func);
 
 	csig = mono_metadata_signature_dup (sig);
 	csig->pinvoke = 0;

+ 1 - 1
mono/metadata/marshal.h

@@ -195,7 +195,7 @@ MonoMethod *
 mono_marshal_get_native_wrapper (MonoMethod *method);
 
 MonoMethod *
-mono_marshal_get_native_func_wrapper (MonoMethodSignature *sig, MonoMarshalSpec **mspecs, gpointer func);
+mono_marshal_get_native_func_wrapper (MonoMethodSignature *sig, MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func);
 
 MonoMethod *
 mono_marshal_get_struct_to_ptr (MonoClass *klass);

+ 9 - 0
mono/metadata/object-internals.h

@@ -912,6 +912,15 @@ typedef struct {
 	MonoBoolean throw_on_unmappable;
 } MonoReflectionDllImportAttribute;
 
+typedef struct {
+	MonoObject object;
+	gint32 call_conv;
+	gint32 charset;
+	MonoBoolean set_last_error;
+	MonoBoolean best_fit_mapping;
+	MonoBoolean throw_on_unmappable;
+} MonoReflectionUnmanagedFunctionPointerAttribute;
+
 typedef struct {
 	MonoObject object;
 	MonoMethod *mhandle;

+ 25 - 0
mono/metadata/reflection.c

@@ -6826,6 +6826,31 @@ mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
 	return FALSE;
 }
 
+MonoObject*
+mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
+{
+	int i, attr_index;
+	MonoClass *klass;
+	MonoArray *attrs;
+
+	attr_index = -1;
+	for (i = 0; i < ainfo->num_attrs; ++i) {
+		klass = ainfo->attrs [i].ctor->klass;
+		if (mono_class_has_parent (klass, attr_klass)) {
+			attr_index = i;
+			break;
+		}
+	}
+	if (attr_index == -1)
+		return NULL;
+
+	attrs = mono_custom_attrs_construct (ainfo);
+	if (attrs)
+		return mono_array_get (attrs, MonoObject*, attr_index);
+	else
+		return NULL;
+}
+
 /*
  * mono_reflection_get_custom_attrs_info:
  * @obj: a reflection object handle

+ 1 - 0
mono/metadata/reflection.h

@@ -76,6 +76,7 @@ MonoCustomAttrInfo* mono_custom_attrs_from_event    (MonoClass *klass, MonoEvent
 MonoCustomAttrInfo* mono_custom_attrs_from_field    (MonoClass *klass, MonoClassField *field);
 MonoCustomAttrInfo* mono_custom_attrs_from_param    (MonoMethod *method, guint32 param);
 gboolean            mono_custom_attrs_has_attr      (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass);
+MonoObject*         mono_custom_attrs_get_attr      (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass);
 void                mono_custom_attrs_free          (MonoCustomAttrInfo *ainfo);