new Type[0]);
private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
new Type[] {typeof(Service.SignalCalledHandler)});
+ private static MethodInfo Service_RemoveSignalCalledMI = typeof(Service).GetMethod("remove_SignalCalled",
+ new Type[] {typeof(Service.SignalCalledHandler)});
private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
new Type[0]);
private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
new Type[0]);
private static MethodInfo Message_SendMI = typeof(Message).GetMethod("Send",
new Type[0]);
+ private static MethodInfo Message_DisposeMI = typeof(Message).GetMethod("Dispose",
+ new Type[0]);
private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
new Type[0]);
private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
// Generate the locals
LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
methodCallL.SetLocalSymInfo("signal");
- LocalBuilder replyL = generator.DeclareLocal(typeof(MethodReturn));
//generator.EmitWriteLine("Signal signal = new Signal(...)");
generator.Emit(OpCodes.Ldsfld, serviceF);
generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, Message_SendMI, null);
+ //generator.EmitWriteLine("signal.Dispose()");
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
+
//generator.EmitWriteLine("return");
generator.Emit(OpCodes.Ret);
}
}
}
+ // Clean up after ourselves
+ //generator.EmitWriteLine("methodCall.Dispose()");
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
+
+ //generator.EmitWriteLine("reply.Dispose()");
+ generator.Emit(OpCodes.Ldloc_1);
+ generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
+
if (method.ReturnType != typeof(void)) {
generator.Emit(OpCodes.Ldloc_3);
}
}
}
- public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI)
+ public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI, FieldInfo deleF)
{
Type[] pars = {typeof(Service), typeof(string)};
ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
CallingConventions.Standard, pars);
ILGenerator generator = constructor.GetILGenerator();
+
+ LocalBuilder handlerL = generator.DeclareLocal (typeof (Service.SignalCalledHandler));
+ handlerL.SetLocalSymInfo ("handler");
+
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, this.introspector.Constructor);
//generator.EmitWriteLine("service = myService");
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_2);
generator.Emit(OpCodes.Stfld, pathF);
-
- //generator.EmitWriteLine("myService.SignalCalled += new Service.SignalCalledHandler(Service_SignalCalled)");
+
+ //generator.EmitWriteLine("handler = new Service.SignalCalledHandler(Service_SignalCalled)");
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldftn, signalCalledMI);
generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
+ generator.Emit(OpCodes.Stloc_0);
+
+ //generator.EmitWriteLine("this.delegate_created = handler");
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.Emit(OpCodes.Stfld, deleF);
+
+ //generator.EmitWriteLine("myService.SignalCalled += handler");
+ generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
//generator.EmitWriteLine("return");
generator.Emit(OpCodes.Ret);
}
+ public void BuildFinalizer (TypeBuilder tb, FieldInfo serviceF, FieldInfo deleF)
+ {
+ // Note that this is a *HORRIBLE* example of how to build a finalizer
+ // It doesn't use the try/finally to chain to Object::Finalize. However,
+ // because that is always going to be a nop, lets just ignore that here.
+ // If you are trying to find the right code, look at what mcs does ;-).
+
+ MethodBuilder mb = tb.DefineMethod("Finalize",
+ MethodAttributes.Family |
+ MethodAttributes.HideBySig |
+ MethodAttributes.Virtual,
+ typeof (void),
+ new Type [0]);
+ ILGenerator generator = mb.GetILGenerator();
+
+ //generator.EmitWriteLine("this.service.SignalCalled -= this.delegate_created");
+ generator.Emit (OpCodes.Ldarg_0);
+ generator.Emit (OpCodes.Ldfld, serviceF);
+ generator.Emit (OpCodes.Ldarg_0);
+ generator.Emit (OpCodes.Ldfld, deleF);
+ generator.EmitCall (OpCodes.Callvirt, Service_RemoveSignalCalledMI, null);
+ generator.Emit (OpCodes.Ret);
+ }
+
public object GetSignalProxy()
{
Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
FieldBuilder pathF = typeB.DefineField("pathName",
typeof(string),
FieldAttributes.Private);
+ FieldBuilder deleF = typeB.DefineField("delegate_created",
+ typeof(Service.SignalCalledHandler),
+ FieldAttributes.Private);
+ BuildFinalizer (typeB, serviceF, deleF);
MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
- BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI);
+ BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI, deleF);
// Build the methods
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
// monodis. Note that in order for this to work you should copy
// the client assembly as a dll file so that monodis can pick it
// up.
- //Service.ProxyAssembly.Save("proxy.dll");
+ //Service.ProxyAssembly.Save(Service.Name + ".proxy.dll");
}
Type [] parTypes = new Type[] {typeof(Service), typeof(string)};