[Mono-dev] COM Interop Remoting Patch

Lluis Sanchez lluis at ximian.com
Thu May 3 10:53:18 EDT 2007


> Hello,
>      Attached is a patch to fix remoting involving COM Interop types.
> I had previsouly broken this unintentionally. COM Interop uses
> transparent proxies, and there was lots of places that didn't
> distinguish between a remoting transparent proxy and a COM Interop
> transparent proxy. To distinguish I check to see if the real proxy
> associated with the transparent proxy is a COM Interop proxy. 
> 
> The main cases I needed to handle was the casting of transparent proxy
> objects, method calls, and field access. For the casting of
> transparent proxies, I added a new field to the MonoRemoteClass for
> the COM Interop vtable. I was previously overwriting the
> default_vtable. For method calls, and probably the most important
> thing to notice, is that I added another check to
> mono_marshal_get_remoting_invoke_with_check to see if a transparent
> proxy is used for COM Interop. This does add some overhead to
> remoting; the overhead should always be emitting a method that simply
> loads all the arguments and calls the wrapped method on the underlying
> managed object the proxy wraps. No real COM Interop code or
> marshalling code should unless the type has a ComImport attribute.
> Unless COM is used the method should never be called, only emitted.
> 
> The field access was done via checks in mono_load_remote_field,
> mono_load_remote_field_new, mono_store_remote_field, and
> mono_store_remote_field_new. This avoids emitting any additional
> checks or methods for remoting wrappers. 
> 
> Please make any suggestions if my changes could be done in a better
> way; especially if my changes related to methods should be more like
> the ones for fields, or vice versa.

The patch looks in general ok to me. I only have a couple of comments:


> Index: mono/mono/metadata/object.c
> ===================================================================
> --- mono/mono/metadata/object.c (revision 75279)
> +++ mono/mono/metadata/object.c (working copy)


> @@ -2589,6 +2598,15 @@
>                 return obj;
>         } else {
>                 /* obj must be already unboxed if needed */
> +               if (obj && mono_object_class(obj) ==
> mono_defaults.transparent_proxy_class) {
> +                       /* Get wrapper method if object is a
> transparent proxy for com interop. 
> +                        * There was no check here for a remoting
> transparent proxy, so I assume that case does
> +                        * not happen... 
> +                        */

This branch of the condition is executed when calling a method which is
not a constructor. I think that it does happen for remote methods, so it
would be good to really check it. Maybe you are adding this com check in
the wrong place.

> +                       MonoTransparentProxy* transparent_proxy =
> (MonoTransparentProxy*)obj;
> +                       if
> (transparent_proxy->rp->object.vtable->klass ==
> mono_defaults.com_interop_proxy_class)
> +                               method =
> mono_marshal_get_cominterop_invoke (method->slot == -1 ? method :
> method->klass->vtable [method->slot]);
> +               }
>                 return mono_runtime_invoke (method, obj, pa, exc);
>         }
>  }
> @@ -4103,8 +4121,12 @@
>         }
>  
>         if (target && target->vtable->klass ==
> mono_defaults.transparent_proxy_class) {
> +               MonoTransparentProxy* transparent_proxy =
> (MonoTransparentProxy*)target;
>                 g_assert (method);
> -               method = mono_marshal_get_remoting_invoke (method);
> +               if (transparent_proxy->rp->object.vtable->klass ==
> mono_defaults.com_interop_proxy_class)
> +                       method = mono_marshal_get_cominterop_invoke
> (method);
> +               else
> +                       method = mono_marshal_get_remoting_invoke
> (method);

Since this check is done in several places, maybe it would be good to
introduce a new method which takes the proxy and the method as
parameters, and returns the correct wrapper method depending on the
proxy type.

>                 delegate->method_ptr = mono_compile_method (method);
>                 MONO_OBJECT_SETREF (delegate, target, target);
>         } else if (mono_method_signature (method)->hasthis &&
> method->klass->valuetype) {
> @@ -4284,6 +4306,12 @@
>         g_assert (this->vtable->klass ==
> mono_defaults.transparent_proxy_class);
>         g_assert (res != NULL);
>  
> +       if (tp->rp->object.vtable->klass ==
> mono_defaults.com_interop_proxy_class) {

Would it make sense to define a macro for checking if a transparent
proxy is a com object? it is being used in several places. 

Thanks,
Lluis.




More information about the Mono-devel-list mailing list