4 using System.Runtime.InteropServices;
5 using System.Diagnostics;
6 using System.Collections;
7 using System.Threading;
8 using System.Reflection;
9 using System.Reflection.Emit;
11 internal class ProxyBuilder
13 private Service service= null;
14 private string pathName = null;
15 private Type type = null;
16 private Introspector introspector = null;
18 private static MethodInfo Service_NameMI = typeof(Service).GetMethod("get_Name",
20 private static MethodInfo Service_ConnectionMI = typeof(Service).GetMethod("get_Connection",
22 private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
23 new Type[] {typeof(Service.SignalCalledHandler)});
24 private static MethodInfo Service_RemoveSignalCalledMI = typeof(Service).GetMethod("remove_SignalCalled",
25 new Type[] {typeof(Service.SignalCalledHandler)});
26 private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
28 private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
30 private static MethodInfo Message_KeyMI = typeof(Message).GetMethod("get_Key",
32 private static MethodInfo Arguments_InitAppendingMI = typeof(Arguments).GetMethod("InitAppending",
34 private static MethodInfo Arguments_AppendMI = typeof(Arguments).GetMethod("Append",
35 new Type[] {typeof(DBusType.IDBusType)});
36 private static MethodInfo Message_SendWithReplyAndBlockMI = typeof(Message).GetMethod("SendWithReplyAndBlock",
38 private static MethodInfo Message_SendMI = typeof(Message).GetMethod("Send",
40 private static MethodInfo Message_DisposeMI = typeof(Message).GetMethod("Dispose",
42 private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
44 private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
46 private static MethodInfo IEnumerator_CurrentMI = typeof(System.Collections.IEnumerator).GetMethod("get_Current",
48 private static MethodInfo Type_GetTypeFromHandleMI = typeof(System.Type).GetMethod("GetTypeFromHandle",
49 new Type[] {typeof(System.RuntimeTypeHandle)});
50 private static MethodInfo IDBusType_GetMI = typeof(DBusType.IDBusType).GetMethod("Get",
51 new Type[] {typeof(System.Type)});
52 private static ConstructorInfo MethodCall_C = typeof(MethodCall).GetConstructor(new Type[] {typeof(Service),
56 private static ConstructorInfo Signal_C = typeof(Signal).GetConstructor(new Type[] {typeof(Service),
60 private static ConstructorInfo Service_SignalCalledHandlerC = typeof(Service.SignalCalledHandler).GetConstructor(new Type[] {typeof(object),
61 typeof(System.IntPtr)});
62 private static MethodInfo String_opEqualityMI = typeof(System.String).GetMethod("op_Equality",
63 new Type[] {typeof(string),
65 private static MethodInfo MulticastDelegate_opInequalityMI = typeof(System.MulticastDelegate).GetMethod("op_Inequality",
66 new Type[] {typeof(System.MulticastDelegate),
67 typeof(System.MulticastDelegate)});
70 public ProxyBuilder(Service service, Type type, string pathName)
72 this.service = service;
73 this.pathName = pathName;
75 this.introspector = Introspector.GetIntrospector(type);
78 private MethodInfo BuildSignalCalled(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
80 Type[] parTypes = {typeof(Signal)};
81 MethodBuilder methodBuilder = typeB.DefineMethod("Service_SignalCalled",
82 MethodAttributes.Private |
83 MethodAttributes.HideBySig,
87 ILGenerator generator = methodBuilder.GetILGenerator();
89 LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
90 enumeratorL.SetLocalSymInfo("enumerator");
92 Label wrongPath = generator.DefineLabel();
93 //generator.EmitWriteLine("if (signal.PathName == pathName) {");
94 generator.Emit(OpCodes.Ldarg_1);
95 generator.EmitCall(OpCodes.Callvirt, Signal_PathNameMI, null);
96 generator.Emit(OpCodes.Ldarg_0);
97 generator.Emit(OpCodes.Ldfld, pathF);
98 generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
99 generator.Emit(OpCodes.Brfalse, wrongPath);
103 foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
104 InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
105 foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
106 EventInfo eventE = (EventInfo) signalEntry.Value;
107 // This is really cheeky since we need to grab the event as a private field.
108 FieldInfo eventF = this.type.GetField(eventE.Name,
109 BindingFlags.NonPublic|
110 BindingFlags.Instance);
112 MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
114 ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
115 parTypes = new Type[pars.Length];
116 for (int parN = 0; parN < pars.Length; parN++) {
117 parTypes[parN] = pars[parN].ParameterType;
118 LocalBuilder parmL = generator.DeclareLocal(parTypes[parN]);
119 parmL.SetLocalSymInfo(pars[parN].Name);
122 Label skip = generator.DefineLabel();
123 //generator.EmitWriteLine(" if (SelectedIndexChanged != null) {");
124 generator.Emit(OpCodes.Ldarg_0);
125 generator.Emit(OpCodes.Ldfld, eventF);
126 generator.Emit(OpCodes.Ldnull);
127 generator.EmitCall(OpCodes.Call, MulticastDelegate_opInequalityMI, null);
128 generator.Emit(OpCodes.Brfalse, skip);
130 //generator.EmitWriteLine(" if (signal.Key == 'la i')");
131 generator.Emit(OpCodes.Ldarg_1);
132 generator.EmitCall(OpCodes.Callvirt, Message_KeyMI, null);
133 generator.Emit(OpCodes.Ldstr, eventE.Name + " " + InterfaceProxy.GetSignature(eventHandler_InvokeMI));
134 generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
135 generator.Emit(OpCodes.Brfalse, skip);
137 //generator.EmitWriteLine("IEnumerator enumerator = signal.Arguments.GetEnumerator()");
138 generator.Emit(OpCodes.Ldarg_1);
139 generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
140 generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
141 generator.Emit(OpCodes.Stloc_0);
143 for (int parN = 0; parN < pars.Length; parN++) {
144 ParameterInfo par = pars[parN];
146 EmitSignalIn(generator, par.ParameterType, parN + localOffset, serviceF);
150 //generator.EmitWriteLine(" SelectedIndexChanged(selectedIndex)");
151 generator.Emit(OpCodes.Ldarg_0);
152 generator.Emit(OpCodes.Ldfld, eventF);
153 for (int parN = 0; parN < pars.Length; parN++) {
154 generator.Emit(OpCodes.Ldloc_S, parN + localOffset);
157 generator.EmitCall(OpCodes.Callvirt, eventHandler_InvokeMI, null);
159 generator.MarkLabel(skip);
160 //generator.EmitWriteLine(" }");
162 localOffset += pars.Length;
166 generator.MarkLabel(wrongPath);
167 //generator.EmitWriteLine("}");
169 //generator.EmitWriteLine("return");
170 generator.Emit(OpCodes.Ret);
172 return methodBuilder;
175 private void BuildSignalHandler(EventInfo eventE,
176 InterfaceProxy interfaceProxy,
177 ref TypeBuilder typeB,
181 MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
182 ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
183 Type[] parTypes = new Type[pars.Length];
184 for (int parN = 0; parN < pars.Length; parN++) {
185 parTypes[parN] = pars[parN].ParameterType;
189 MethodBuilder methodBuilder = typeB.DefineMethod("Proxy_" + eventE.Name,
190 MethodAttributes.Public |
191 MethodAttributes.HideBySig |
192 MethodAttributes.Virtual,
195 ILGenerator generator = methodBuilder.GetILGenerator();
197 for (int parN = 0; parN < pars.Length; parN++) {
198 methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
201 // Generate the locals
202 LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
203 methodCallL.SetLocalSymInfo("signal");
205 //generator.EmitWriteLine("Signal signal = new Signal(...)");
206 generator.Emit(OpCodes.Ldsfld, serviceF);
207 generator.Emit(OpCodes.Ldarg_0);
208 generator.Emit(OpCodes.Ldfld, pathF);
209 generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
210 generator.Emit(OpCodes.Ldstr, eventE.Name);
211 generator.Emit(OpCodes.Newobj, Signal_C);
212 generator.Emit(OpCodes.Stloc_0);
214 //generator.EmitWriteLine("signal.Arguments.InitAppending()");
215 generator.Emit(OpCodes.Ldloc_0);
216 generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
217 generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
219 for (int parN = 0; parN < pars.Length; parN++) {
220 ParameterInfo par = pars[parN];
222 EmitIn(generator, par.ParameterType, parN, serviceF);
226 //generator.EmitWriteLine("signal.Send()");
227 generator.Emit(OpCodes.Ldloc_0);
228 generator.EmitCall(OpCodes.Callvirt, Message_SendMI, null);
230 //generator.EmitWriteLine("signal.Dispose()");
231 generator.Emit(OpCodes.Ldloc_0);
232 generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
234 //generator.EmitWriteLine("return");
235 generator.Emit(OpCodes.Ret);
238 private void BuildMethod(MethodInfo method,
239 InterfaceProxy interfaceProxy,
240 ref TypeBuilder typeB,
244 ParameterInfo[] pars = method.GetParameters();
245 Type[] parTypes = new Type[pars.Length];
246 for (int parN = 0; parN < pars.Length; parN++) {
247 parTypes[parN] = pars[parN].ParameterType;
251 MethodBuilder methodBuilder = typeB.DefineMethod(method.Name,
252 MethodAttributes.Public |
253 MethodAttributes.HideBySig |
254 MethodAttributes.Virtual,
257 ILGenerator generator = methodBuilder.GetILGenerator();
259 for (int parN = 0; parN < pars.Length; parN++) {
260 methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
263 // Generate the locals
264 LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
265 methodCallL.SetLocalSymInfo("methodCall");
266 LocalBuilder replyL = generator.DeclareLocal(typeof(MethodReturn));
267 replyL.SetLocalSymInfo("reply");
268 LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
269 enumeratorL.SetLocalSymInfo("enumerator");
271 if (method.ReturnType != typeof(void)) {
272 LocalBuilder retvalL = generator.DeclareLocal(method.ReturnType);
273 retvalL.SetLocalSymInfo("retval");
276 //generator.EmitWriteLine("MethodCall methodCall = new MethodCall(...)");
277 generator.Emit(OpCodes.Ldsfld, serviceF);
278 generator.Emit(OpCodes.Ldarg_0);
279 generator.Emit(OpCodes.Ldfld, pathF);
280 generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
281 generator.Emit(OpCodes.Ldstr, method.Name);
282 generator.Emit(OpCodes.Newobj, MethodCall_C);
283 generator.Emit(OpCodes.Stloc_0);
285 //generator.EmitWriteLine("methodCall.Arguments.InitAppending()");
286 generator.Emit(OpCodes.Ldloc_0);
287 generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
288 generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
290 for (int parN = 0; parN < pars.Length; parN++) {
291 ParameterInfo par = pars[parN];
293 EmitIn(generator, par.ParameterType, parN, serviceF);
297 //generator.EmitWriteLine("MethodReturn reply = methodCall.SendWithReplyAndBlock()");
298 generator.Emit(OpCodes.Ldloc_0);
299 generator.EmitCall(OpCodes.Callvirt, Message_SendWithReplyAndBlockMI, null);
300 generator.Emit(OpCodes.Stloc_1);
302 //generator.EmitWriteLine("IEnumerator enumeartor = reply.Arguments.GetEnumerator()");
303 generator.Emit(OpCodes.Ldloc_1);
304 generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
305 generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
306 generator.Emit(OpCodes.Stloc_2);
308 // handle the return value
309 if (method.ReturnType != typeof(void)) {
310 EmitOut(generator, method.ReturnType, 0);
313 for (int parN = 0; parN < pars.Length; parN++) {
314 ParameterInfo par = pars[parN];
315 if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
316 EmitOut(generator, par.ParameterType, parN);
320 // Clean up after ourselves
321 //generator.EmitWriteLine("methodCall.Dispose()");
322 generator.Emit(OpCodes.Ldloc_0);
323 generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
325 //generator.EmitWriteLine("reply.Dispose()");
326 generator.Emit(OpCodes.Ldloc_1);
327 generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
329 if (method.ReturnType != typeof(void)) {
330 generator.Emit(OpCodes.Ldloc_3);
333 generator.Emit(OpCodes.Ret);
335 // Generate the method
336 typeB.DefineMethodOverride(methodBuilder, method);
339 private void EmitSignalIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
341 //generator.EmitWriteLine("enumerator.MoveNext()");
342 generator.Emit(OpCodes.Ldloc_0);
343 generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
345 Type outParType = Arguments.MatchType(parType);
346 //generator.EmitWriteLine("int selectedIndex = (int) ((DBusType.IDBusType) enumerator.Current).Get(typeof(int))");
347 generator.Emit(OpCodes.Pop);
348 generator.Emit(OpCodes.Ldloc_0);
349 generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
350 generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
351 generator.Emit(OpCodes.Ldtoken, parType);
352 generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
353 generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
354 // Call the DBusType EmitMarshalOut to make it emit itself
355 object[] pars = new object[] {generator, parType, true};
356 outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
357 generator.Emit(OpCodes.Stloc_S, parN);
361 private void EmitIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
363 Type inParType = Arguments.MatchType(parType);
364 //generator.EmitWriteLine("methodCall.Arguments.Append(...)");
365 generator.Emit(OpCodes.Ldloc_0);
366 generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
367 generator.Emit(OpCodes.Ldarg_S, parN + 1);
369 // Call the DBusType EmitMarshalIn to make it emit itself
370 object[] pars = new object[] {generator, parType};
371 inParType.InvokeMember("EmitMarshalIn", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
373 generator.Emit(OpCodes.Ldsfld, serviceF);
374 generator.Emit(OpCodes.Newobj, Arguments.GetDBusTypeConstructor(inParType, parType));
375 generator.EmitCall(OpCodes.Callvirt, Arguments_AppendMI, null);
378 private void EmitOut(ILGenerator generator, Type parType, int parN)
380 Type outParType = Arguments.MatchType(parType);
381 //generator.EmitWriteLine("enumerator.MoveNext()");
382 generator.Emit(OpCodes.Ldloc_2);
383 generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
385 //generator.EmitWriteLine("return (" + parType + ") ((DBusType.IDBusType) enumerator.Current).Get(typeof(" + parType + "))");
386 generator.Emit(OpCodes.Pop);
388 generator.Emit(OpCodes.Ldarg_S, parN + 1);
391 generator.Emit(OpCodes.Ldloc_2);
392 generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
393 generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
394 generator.Emit(OpCodes.Ldtoken, parType);
395 generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
396 generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
398 // Call the DBusType EmitMarshalOut to make it emit itself
399 object[] pars = new object[] {generator, parType, parN == 0};
400 outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
403 generator.Emit(OpCodes.Stloc_3);
407 public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI, FieldInfo deleF)
409 Type[] pars = {typeof(Service), typeof(string)};
410 ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
411 MethodAttributes.Public,
412 CallingConventions.Standard, pars);
414 ILGenerator generator = constructor.GetILGenerator();
415 generator.Emit(OpCodes.Ldarg_0);
416 generator.Emit(OpCodes.Call, this.introspector.Constructor);
417 //generator.EmitWriteLine("service = myService");
418 generator.Emit(OpCodes.Ldarg_1);
419 generator.Emit(OpCodes.Stsfld, serviceF);
420 //generator.EmitWriteLine("this.pathName = pathName");
421 generator.Emit(OpCodes.Ldarg_0);
422 generator.Emit(OpCodes.Ldarg_2);
423 generator.Emit(OpCodes.Stfld, pathF);
425 //generator.EmitWriteLine("this.delegate_created = new Service.SignalCalledHandler(Service_SignalCalled)");
426 generator.Emit(OpCodes.Ldarg_1);
427 generator.Emit(OpCodes.Ldarg_0);
428 generator.Emit(OpCodes.Ldftn, signalCalledMI);
429 generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
430 generator.Emit(OpCodes.Stloc_0);
431 generator.Emit(OpCodes.Ldarg_0);
432 generator.Emit(OpCodes.Ldloc_0);
433 generator.Emit(OpCodes.Stfld, deleF);
435 //generator.EmitWriteLine("myService.SignalCalled += this.delegate_created");
436 generator.Emit(OpCodes.Ldloc_0);
437 generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
439 //generator.EmitWriteLine("return");
440 generator.Emit(OpCodes.Ret);
443 public void BuildSignalConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
445 Type[] pars = {typeof(Service), typeof(string)};
446 ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
447 MethodAttributes.Public,
448 CallingConventions.Standard, pars);
450 ILGenerator generator = constructor.GetILGenerator();
451 generator.Emit(OpCodes.Ldarg_0);
452 generator.Emit(OpCodes.Call, this.introspector.Constructor);
453 //generator.EmitWriteLine("service = myService");
454 generator.Emit(OpCodes.Ldarg_1);
455 generator.Emit(OpCodes.Stsfld, serviceF);
456 //generator.EmitWriteLine("this.pathName = pathName");
457 generator.Emit(OpCodes.Ldarg_0);
458 generator.Emit(OpCodes.Ldarg_2);
459 generator.Emit(OpCodes.Stfld, pathF);
461 //generator.EmitWriteLine("return");
462 generator.Emit(OpCodes.Ret);
465 public void BuildFinalizer (TypeBuilder tb, FieldInfo fi)
467 // Note that this is a *HORRIBLE* example of how to build a finalizer
468 // It doesn't use the try/finally to chain to Object::Finalize. However,
469 // because that is always going to be a nop, lets just ignore that here.
470 // If you are trying to find the right code, look at what mcs does ;-).
472 MethodBuilder mb = tb.DefineMethod("Finalize",
473 MethodAttributes.Family |
474 MethodAttributes.HideBySig |
475 MethodAttributes.Virtual,
478 ILGenerator generator = mb.GetILGenerator();
480 //generator.EmitWriteLine("this.service.SignalCalled -= this.delegate_created");
481 generator.Emit (OpCodes.Ldfld, fi);
482 generator.Emit (OpCodes.Call, Service_RemoveSignalCalledMI);
483 generator.Emit (OpCodes.Ret);
486 public object GetSignalProxy()
488 Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
490 if (proxyType == null) {
492 TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".SignalProxy",
493 TypeAttributes.Public,
496 FieldBuilder serviceF = typeB.DefineField("service",
498 FieldAttributes.Private |
499 FieldAttributes.Static);
500 FieldBuilder pathF = typeB.DefineField("pathName",
502 FieldAttributes.Private);
504 BuildSignalConstructor(ref typeB, serviceF, pathF);
506 // Build the signal handlers
507 foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
508 InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
509 foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
510 EventInfo eventE = (EventInfo) signalEntry.Value;
511 BuildSignalHandler(eventE, interfaceProxy, ref typeB, serviceF, pathF);
515 proxyType = typeB.CreateType();
517 // Uncomment the following line to produce a DLL of the
518 // constructed assembly which can then be examined using
519 // monodis. Note that in order for this to work you should copy
520 // the client assembly as a dll file so that monodis can pick it
522 //Service.ProxyAssembly.Save("proxy.dll");
525 Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
526 object [] pars = new object[] {Service, pathName};
528 ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
529 object instance = constructor.Invoke(pars);
534 public object GetProxy()
536 Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".Proxy");
538 if (proxyType == null) {
540 TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".Proxy", TypeAttributes.Public, this.type);
542 FieldBuilder serviceF = typeB.DefineField("service",
544 FieldAttributes.Private |
545 FieldAttributes.Static);
546 FieldBuilder pathF = typeB.DefineField("pathName",
548 FieldAttributes.Private);
549 FieldBuilder deleF = typeB.DefineField("delegate_created",
550 typeof(Service.SignalCalledHandler),
551 FieldAttributes.Private);
552 BuildFinalizer (typeB, deleF);
554 MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
555 BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI, deleF);
558 foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
559 InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
560 foreach (DictionaryEntry methodEntry in interfaceProxy.Methods) {
561 MethodInfo method = (MethodInfo) methodEntry.Value;
562 BuildMethod(method, interfaceProxy, ref typeB, serviceF, pathF);
566 proxyType = typeB.CreateType();
568 // Uncomment the following line to produce a DLL of the
569 // constructed assembly which can then be examined using
570 // monodis. Note that in order for this to work you should copy
571 // the client assembly as a dll file so that monodis can pick it
573 //Service.ProxyAssembly.Save("proxy.dll");
576 Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
577 object [] pars = new object[] {Service, pathName};
579 ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
580 object instance = constructor.Invoke(pars);
584 private Service Service
591 private string ObjectName
594 return this.introspector.ToString();