public void Initialize <T>(ref T value) { lock (messageUtilsLock) { object obj = (object)value; Type t = typeof(T); marshaler.EnterContext(); foreach (FieldInfo field in t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { Type ft = field.FieldType; if (ft.IsEnum) { bool exclusive = !MarshalingDescriptor.HasAttribute(ft, typeof(FlagsAttribute)); if (exclusive) { FieldInfo[] df = ft.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (df != null && df.Length > 0) { field.SetValue(obj, df[0].GetRawConstantValue()); } } } else if (ft.IsArray) { int size, length; marshaler.GetAdvocatedSize(new MarshalingDescriptor(ft, field), out size, out length); if (size >= 0) { if (ft.IsArray) { field.SetValue(obj, Array.CreateInstance(ft.GetElementType(), size)); } else { field.SetValue(obj, CreateSequence(ft.GetGenericArguments()[0], size)); } } } marshaler.DefineSymbol(field.Name, field.GetValue(obj)); } marshaler.ExitContext(); List <MethodInfo> ms; if (initializers.TryGetValue(t, out (ms))) { foreach (MethodInfo m in ms) { object[] args = new object[] { obj }; m.Invoke(this, args); obj = args[0]; } } value = (T)obj; } }
protected override IMessage Invoke(IMethodCallMessage mcall) { Marshaler marshaler = new Marshaler(site, NativeMarshalingConfiguration.Configuration); foreach (Type type in proxiedType.Assembly.GetTypes()) { marshaler.DefineCustomType(type.Name, type); } if (mcall.MethodBase == getHandleMethod) return GetHandle(mcall); if (mcall.MethodBase == setHandleMethod) return SetHandle(mcall); Initialize(); RpcStub stub; if (!stubs.TryGetValue(mcall.MethodBase, out stub)) throw new InvalidOperationException(String.Format("cannot find stub for method '{0}'", mcall.MethodBase)); // marshal parameters int n = stub.parameters.Length; int actualsOffs = handleImplicit ? 1 : 0; object[] actuals = new object[n + actualsOffs]; if (handleImplicit) { if (handle == null) marshaler.TestAssumeFail( "handle undefined for rpc interface '{0}' with implicit handle passing", proxiedType); IntPtr ptr = Marshal.StringToHGlobalUni(handle); marshaler.MarkMemoryForDispose(ptr); actuals[0] = ptr; } marshaler.EnterContext(); for (int i = 0; i < n; i++) { if (!stub.parameters[i].IsOut) { marshaler.DefineSymbol(mcall.GetArgName(i), mcall.Args[i]); } } ParameterInfo[] parameterInfos = mcall.MethodBase.GetParameters(); for (int pass = 0; pass < 2; pass++) { for (int i = 0; i < n; i++) { if (pass == 0 && stub.parameters[i].HasDynamicExpression) { continue; } if (pass == 1 && !stub.parameters[i].HasDynamicExpression) { continue; } stub.parameters[i].AllocateMemoryRegion(marshaler, mcall.Args[i]); RpcParameter rp = stub.parameters[i]; if (rp.marshallingRegion != null) rp.marshallingRegion.TryReset(); if (!rp.IsOut && mcall.Args[i] != null) { object value = mcall.Args[i]; // Validate the value of the parameter. if (this.needAutoValidate) CheckParameter(parameterInfos[i], value, mcall, marshaler.SymbolStore); marshaler.MarshalInto(rp.context, rp.marshallingRegion, mcall.Args[i]); } else { marshaler.EnterRegion(rp.marshallingRegion); marshaler.Clear(marshaler.GetSize(rp.context, null)); marshaler.ExitRegion(); } if (!rp.IsByRef) { actuals[i + actualsOffs] = rp.Get(); } else { if (mcall.Args[i] == null && !rp.IsOut) { actuals[i + actualsOffs] = IntPtr.Zero; } else { actuals[i + actualsOffs] = rp.marshallingRegion.NativeMemory; } } marshaler.DefineSymbol(mcall.GetArgName(i), actuals[i + actualsOffs]); } } // call object result; try { result = stub.stubMethod.Invoke(null, actuals); } catch (TargetInvocationException e) { throw e.InnerException; } // marshal output parameters object[] resultArgs = new object[n]; marshaler.IsProbingUnmarshaling = true; for (int pass = 0; pass < 2; pass++) { for (int i = 0; i < n; i++) { RpcParameter rp = stub.parameters[i]; if (rp.marshallingRegion != null) rp.marshallingRegion.TryReset(); if (rp.IsByRef) { object res = resultArgs[i] = marshaler.UnmarshalFrom(rp.context, rp.marshallingRegion); if (marshaler.IsProbingUnmarshaling == false) { RpcAdapterValidate(res, rp.context.Attributes, marshaler.SymbolStore); if (rp.IsOut && marshaler.GetNativeType(rp.context) == typeof(IntPtr)) { foreach (IntPtr ptr in marshaler.ForeignMemory) { if (ptr != IntPtr.Zero && rpcFreeMethod != null) { rpcFreeMethod.Invoke(null, new object[] { ptr }); } } } } marshaler.ForeignMemory.Clear(); if (!rp.IsByRef) { marshaler.DefineSymbol(mcall.GetArgName(i), rp.Get()); } else { marshaler.DefineSymbol(mcall.GetArgName(i), rp.marshallingRegion.NativeMemory); } } else { resultArgs[i] = mcall.Args[i]; } } marshaler.IsProbingUnmarshaling = false; } if (stub.returnParameter.nativeType != typeof(void)) { stub.returnParameter.AllocateMemoryRegion(marshaler, result); stub.returnParameter.marshallingRegion.TryReset(); stub.returnParameter.Set(result); result = marshaler.UnmarshalFrom( stub.returnParameter.context, stub.returnParameter.marshallingRegion); RpcAdapterValidate(result, null, null); } marshaler.ExitContext(); marshaler.FreeMemory(); marshaler.Dispose(); marshaler = null; CheckOperation(mcall); ReturnMessage mret = new ReturnMessage(result, resultArgs, resultArgs.Length, mcall.LogicalCallContext, mcall); return mret; }