}
internal class CADObjRef {
- ObjRef objref;
- public int SourceDomain;
+ internal ObjRef objref;
+ internal int SourceDomain;
+ internal byte[] TypeInfo;
public CADObjRef (ObjRef o, int sourceDomain) {
objref = o;
+ TypeInfo = o.SerializeType ();
SourceDomain = sourceDomain;
}
-
+
public string TypeName {
get { return objref.TypeInfo.TypeName; }
}
}
}
+ [Serializable]
+ internal class CADMethodRef
+ {
+ Type[] GetTypes (string[] typeArray)
+ {
+ Type[] res = new Type [typeArray.Length];
+ for (int i = 0; i < typeArray.Length; ++i)
+ res [i] = Type.GetType (typeArray [i], true);
+ return res;
+ }
+
+ bool ctor;
+ string typeName;
+ string methodName;
+ string[] param_names;
+ string[] generic_arg_names;
+
+ public MethodBase Resolve ()
+ {
+ Type type = Type.GetType (typeName, true);
+ MethodBase sig_cand = null;
+ Type[] param_types = GetTypes (param_names);
+ if (ctor)
+ sig_cand = type.GetConstructor (BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, param_types, null);
+ else
+ sig_cand = type.GetMethod (methodName, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, param_types, null);
+
+ if (sig_cand != null && generic_arg_names != null)
+ sig_cand = ((MethodInfo)sig_cand).MakeGenericMethod (GetTypes (generic_arg_names));
+
+ if (sig_cand == null)
+ throw new RemotingException ($"Method '{methodName}' not found in type '{typeName}'");
+
+ return sig_cand;
+ }
+
+ public CADMethodRef (IMethodMessage msg)
+ {
+ MethodBase method = msg.MethodBase;
+ typeName = method.DeclaringType.AssemblyQualifiedName;
+ ctor = method.IsConstructor;
+ methodName = method.Name;
+
+ if (!ctor && method.IsGenericMethod) {
+ var ga = method.GetGenericArguments ();
+ generic_arg_names = new string [ga.Length];
+ for (int i = 0; i < ga.Length; ++i)
+ generic_arg_names [i] = ga [i].AssemblyQualifiedName;
+
+ method = ((MethodInfo)method).GetGenericMethodDefinition ();
+ }
+
+ var param_types = method.GetParameters ();
+ param_names = new string [param_types.Length];
+ for (int i = 0; i < param_types.Length; ++i)
+ param_names [i] = param_types [i].ParameterType.AssemblyQualifiedName;
+ }
+ }
+
internal class CADMessageBase {
protected object [] _args;
protected byte [] _serializedArgs = null;
protected int _propertyCount = 0;
protected CADArgHolder _callContext;
-
+ internal byte[] serializedMethod;
+
+ public CADMessageBase (IMethodMessage msg) {
+ CADMethodRef methodRef = new CADMethodRef (msg);
+ serializedMethod = CADSerializer.SerializeObject (methodRef).GetBuffer ();
+ }
+
+ internal MethodBase GetMethod ()
+ {
+ CADMethodRef methRef = (CADMethodRef)CADSerializer.DeserializeObjectSafe (serializedMethod);
+
+ return methRef.Resolve ();
+ }
+
+ static protected Type [] GetSignature (MethodBase methodBase, bool load)
+ {
+ ParameterInfo[] pars = methodBase.GetParameters ();
+ Type[] signature = new Type [pars.Length];
+ for (int n=0; n<pars.Length; n++) {
+ // The parameter types may also be loaded from a different assembly, so we need
+ // to load them again
+ if (load)
+ signature [n] = Type.GetType (pars [n].ParameterType.AssemblyQualifiedName, true);
+ else
+ signature [n] = pars [n].ParameterType;
+ }
+ return signature;
+ }
+
// Helper to marshal properties
internal static int MarshalProperties (IDictionary dict, ref ArrayList args) {
IDictionary serDict = dict;
int count = 0;
- MethodDictionary msgDict = dict as MethodDictionary;
+ MessageDictionary msgDict = dict as MessageDictionary;
if (null != msgDict) {
- if (msgDict.HasInternalProperties) {
- serDict = msgDict.InternalProperties;
+ if (msgDict.HasUserData ()) {
+ serDict = msgDict.InternalDictionary;
if (null != serDict) {
foreach (DictionaryEntry e in serDict) {
if (null == args)
CADObjRef objref = arg as CADObjRef;
if (null != objref) {
- string typeName = string.Copy (objref.TypeName);
- string uri = string.Copy (objref.URI);
- int domid = objref.SourceDomain;
-
- ChannelInfo cinfo = new ChannelInfo (new CrossAppDomainData (domid));
- ObjRef localRef = new ObjRef (typeName, uri, cinfo);
+ ObjRef localRef = objref.objref.DeserializeInTheCurrentDomain (objref.SourceDomain, objref.TypeInfo);
return RemotingServices.Unmarshal (localRef);
}
return unmarshalledArgs;
}
-
+
protected void SaveLogicalCallContext (IMethodMessage msg, ref ArrayList serializeList)
{
if (msg.LogicalCallContext != null && msg.LogicalCallContext.HasInfo)
// Used when passing a IMethodCallMessage between appdomains
internal class CADMethodCallMessage : CADMessageBase {
string _uri;
-
- internal RuntimeMethodHandle MethodHandle;
- internal string FullTypeName;
-
+
internal string Uri {
get {
return _uri;
return new CADMethodCallMessage (msg);
}
- internal CADMethodCallMessage (IMethodCallMessage callMsg) {
+ internal CADMethodCallMessage (IMethodCallMessage callMsg): base (callMsg) {
_uri = callMsg.Uri;
- MethodHandle = callMsg.MethodBase.MethodHandle;
- FullTypeName = callMsg.MethodBase.DeclaringType.AssemblyQualifiedName;
ArrayList serializeList = null;
}
}
- internal MethodBase GetMethod ()
- {
- MethodBase methodBase = MethodBase.GetMethodFromHandle (MethodHandle);
- Type tt = Type.GetType (FullTypeName);
-
- if (tt != methodBase.DeclaringType) {
- // The target domain has loaded the type from a different assembly.
- // We need to locate the correct type and get the method from it
- ParameterInfo[] pars = methodBase.GetParameters ();
- Type[] signature = new Type [pars.Length];
- for (int n=0; n<pars.Length; n++) {
- // The parameter types may also be loaded from a different assembly, so we need
- // to load them again
- signature [n] = Type.GetType (pars [n].ParameterType.AssemblyQualifiedName, true);
- }
- MethodBase mb = tt.GetMethod (methodBase.Name, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, signature, null);
- if (mb == null)
- throw new RemotingException ("Method '" + methodBase.Name + "' not found in type '" + tt + "'");
- return mb;
- }
- return methodBase;
- }
}
// Used when passing a IMethodReturnMessage between appdomains
internal class CADMethodReturnMessage : CADMessageBase {
object _returnValue;
CADArgHolder _exception = null;
+#pragma warning disable 414
+ Type [] _sig;
+#pragma warning restore
static internal CADMethodReturnMessage Create (IMessage callMsg) {
IMethodReturnMessage msg = callMsg as IMethodReturnMessage;
return new CADMethodReturnMessage (msg);
}
- internal CADMethodReturnMessage(IMethodReturnMessage retMsg) {
+ internal CADMethodReturnMessage(IMethodReturnMessage retMsg): base (retMsg) {
ArrayList serializeList = null;
_propertyCount = MarshalProperties (retMsg.Properties, ref serializeList);
_returnValue = MarshalArgument ( retMsg.ReturnValue, ref serializeList);
_args = MarshalArguments ( retMsg.Args, ref serializeList);
+ _sig = GetSignature (GetMethod (), true);
+
if (null != retMsg.Exception) {
if (null == serializeList)
serializeList = new ArrayList();
internal object [] GetArgs (ArrayList args) {
return UnmarshalArguments (_args, args);
}
-
+
internal object GetReturnValue (ArrayList args) {
return UnmarshalArgument (_returnValue, args);
}