2 // System.Runtime.Remoting.Proxies.RealProxy.cs
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Lluis Sanchez (lsg@ctv.es)
9 // (C) 2001 Ximian, Inc. http://www.ximian.com
13 using System.Reflection;
14 using System.Runtime.Remoting;
15 using System.Runtime.Remoting.Messaging;
16 using System.Runtime.Remoting.Activation;
17 using System.Runtime.Remoting.Contexts;
18 using System.Runtime.CompilerServices;
19 using System.Runtime.Serialization;
22 namespace System.Runtime.Remoting.Proxies
24 internal class TransparentProxy {
27 bool _custom_type_info;
30 public abstract class RealProxy {
33 internal Context _targetContext;
34 MarshalByRefObject _server;
35 internal Identity _objectIdentity;
39 protected RealProxy ()
41 throw new NotImplementedException ();
44 protected RealProxy (Type classToProxy) : this(classToProxy, (IntPtr) 0, null)
48 internal RealProxy (Type classToProxy, ClientIdentity identity) : this(classToProxy, (IntPtr) 0, null)
50 _objectIdentity = identity;
53 protected RealProxy (Type classToProxy, IntPtr stub, object stubData)
55 if (!classToProxy.IsMarshalByRef && !classToProxy.IsInterface)
56 throw new ArgumentException("object must be MarshalByRef");
58 this.class_to_proxy = classToProxy;
63 [MethodImplAttribute(MethodImplOptions.InternalCall)]
64 extern static Type InternalGetProxyType (object transparentProxy);
66 public Type GetProxiedType()
69 if (class_to_proxy.IsInterface) return typeof(MarshalByRefObject);
70 else return class_to_proxy;
72 return InternalGetProxyType (_objTP);
75 public virtual ObjRef CreateObjRef (Type requestedType)
77 return RemotingServices.Marshal ((MarshalByRefObject) GetTransparentProxy(), null, requestedType);
80 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
82 Object obj = GetTransparentProxy();
\r
83 RemotingServices.GetObjectData (obj, info, context);
\r
86 internal Identity ObjectIdentity
88 get { return _objectIdentity; }
89 set { _objectIdentity = value; }
93 public virtual IntPtr GetCOMIUnknown (bool fIsMarshalled)
95 throw new NotImplementedException ();
99 public virtual void SetCOMIUnknown (IntPtr i)
101 throw new NotImplementedException ();
105 public virtual IntPtr SupportsInterface (ref Guid iid)
107 throw new NotImplementedException ();
110 public static object GetStubData (RealProxy rp)
115 public static void SetStubData (RealProxy rp, object stubData)
117 rp._stubData = stubData;
120 public abstract IMessage Invoke (IMessage msg);
122 /* this is called from unmanaged code */
123 internal static object PrivateInvoke (RealProxy rp, IMessage msg, out Exception exc,
124 out object [] out_args)
126 MonoMethodMessage mMsg = (MonoMethodMessage) msg;
127 mMsg.LogicalCallContext = CallContext.CreateLogicalCallContext();
129 if (mMsg.CallType == CallType.BeginInvoke)
130 mMsg.AsyncResult.CallMessage = mMsg; // TODO: do this in the runtime
132 IMethodReturnMessage res_msg = null;
133 res_msg = (IMethodReturnMessage)rp.Invoke (msg);
135 if (res_msg.LogicalCallContext != null && res_msg.LogicalCallContext.HasInfo)
136 CallContext.UpdateCurrentCallContext (res_msg.LogicalCallContext);
138 exc = res_msg.Exception;
140 // todo: remove throw exception from the runtime invoke
143 throw exc.FixRemotingException();
145 else if (res_msg is IConstructionReturnMessage || mMsg.CallType == CallType.BeginInvoke) {
146 out_args = res_msg.OutArgs;
148 else if (mMsg.CallType == CallType.Sync) {
149 out_args = ProcessResponse (res_msg, mMsg);
151 else if (mMsg.CallType == CallType.EndInvoke) {
152 out_args = ProcessResponse (res_msg, mMsg.AsyncResult.CallMessage);
155 out_args = res_msg.OutArgs;
158 return res_msg.ReturnValue;
161 [MethodImplAttribute(MethodImplOptions.InternalCall)]
162 internal extern virtual object InternalGetTransparentProxy (string className);
164 public virtual object GetTransparentProxy ()
169 IRemotingTypeInfo rti = this as IRemotingTypeInfo;
173 if (name == typeof(MarshalByRefObject).AssemblyQualifiedName)
174 name = class_to_proxy.AssemblyQualifiedName;
177 name = class_to_proxy.AssemblyQualifiedName;
179 _objTP = InternalGetTransparentProxy (name);
185 public IConstructionReturnMessage InitializeServerObject(IConstructionCallMessage ctorMsg)
187 throw new NotImplementedException();
190 protected void AttachServer(MarshalByRefObject s)
195 protected MarshalByRefObject DetachServer()
197 MarshalByRefObject ob = _server;
202 protected MarshalByRefObject GetUnwrappedServer()
207 static object[] ProcessResponse (IMethodReturnMessage mrm, IMethodCallMessage call)
211 MethodInfo mi = (MethodInfo) call.MethodBase;
212 if (mrm.ReturnValue != null && !mi.ReturnType.IsInstanceOfType (mrm.ReturnValue))
213 throw new RemotingException ("Return value has an invalid type");
215 // Check out parameters
217 if (mrm.OutArgCount > 0)
219 ParameterInfo[] parameters = mi.GetParameters();
221 foreach (ParameterInfo par in parameters)
222 if (par.ParameterType.IsByRef) no++;
224 object[] outArgs = new object [no];
228 foreach (ParameterInfo par in parameters)
230 if (par.IsOut && !par.ParameterType.IsByRef)
232 // Special marshalling required
234 object outArg = mrm.GetOutArg (nout++);
235 if (outArg != null) {
236 object local = call.GetArg (par.Position);
237 if (local == null) throw new RemotingException ("Unexpected null value in local out parameter '" + par.Position + " " + par.Name + "'");
238 RemotingServices.UpdateOutArgObject (par, local, outArg);
241 else if (par.ParameterType.IsByRef)
243 object outArg = mrm.GetOutArg (nout++);
244 if (outArg != null && !par.ParameterType.IsInstanceOfType (outArg))
246 throw new RemotingException ("Return argument '" + par.Name + "' has an invalid type");
248 outArgs [narg++] = outArg;
254 return new object [0];