gunichar2** rgszNames, guint32 cNames,
guint32 lcid, gint32 *rgDispId)
{
- int i,ret = MONO_S_OK;
- MonoMethod* method;
- gchar* methodname;
- MonoClass *klass = NULL;
- MonoCCW* ccw = ccwe->ccw;
- MonoObject* object = mono_gchandle_get_target (ccw->gc_handle);
-
- g_assert (object);
- klass = mono_object_class (object);
-
- if (!mono_domain_get ())
- mono_thread_attach (mono_get_root_domain ());
-
- for (i=0; i < cNames; i++) {
- methodname = mono_unicode_to_external (rgszNames[i]);
-
- method = mono_class_get_method_from_name(klass, methodname, -1);
- if (method)
- rgDispId[i] = (gint32)method->token;
- else {
- rgDispId[i] = MONO_E_DISPID_UNKNOWN;
- ret = MONO_E_DISP_E_UNKNOWNNAME;
- }
- }
-
- return ret;
+ static MonoClass *ComDispIdAttribute = NULL;
+ MonoCustomAttrInfo *cinfo = NULL;
+ int i,ret = MONO_S_OK;
+ MonoMethod* method;
+ gchar* methodname;
+ MonoClass *klass = NULL;
+ MonoCCW* ccw = ccwe->ccw;
+ MonoObject* object = mono_gchandle_get_target (ccw->gc_handle);
+
+ /* Handle DispIdAttribute */
+ if (!ComDispIdAttribute)
+ ComDispIdAttribute = mono_class_from_name (mono_defaults.corlib, "System.Runtime.InteropServices", "DispIdAttribute");
+
+ g_assert (object);
+ klass = mono_object_class (object);
+
+ if (!mono_domain_get ())
+ mono_thread_attach (mono_get_root_domain ());
+
+ for (i=0; i < cNames; i++) {
+ methodname = mono_unicode_to_external (rgszNames[i]);
+
+ method = mono_class_get_method_from_name(klass, methodname, -1);
+ if (method) {
+ cinfo = mono_custom_attrs_from_method (method);
+ if (cinfo) {
+ MonoObject *result = mono_custom_attrs_get_attr (cinfo, ComDispIdAttribute);
+
+ if (result)
+ rgDispId[i] = *(gint32*)mono_object_unbox (result);
+ else
+ rgDispId[i] = (gint32)method->token;
+
+ if (!cinfo->cached)
+ mono_custom_attrs_free (cinfo);
+ }
+ else
+ rgDispId[i] = (gint32)method->token;
+ } else {
+ rgDispId[i] = MONO_E_DISPID_UNKNOWN;
+ ret = MONO_E_DISP_E_UNKNOWNNAME;
+ }
+ }
+
+ return ret;
}
static int STDCALL