- 浏览: 399614 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (309)
- xaml C# wpf (0)
- scala java inner clas (1)
- Tools UML Eclipse UML2 (1)
- Timer .NET Framework (1)
- perl (6)
- python function paramter (1)
- Python Docstring (1)
- Python how to compare types (1)
- Python (8)
- java (5)
- C# (76)
- C# WPF (0)
- p4 (0)
- WPF (46)
- .net (6)
- xaml (1)
- javascript (40)
- windows (10)
- scala (4)
- winform (1)
- c++ (48)
- tools (12)
- cmd (1)
- os (0)
- CI (0)
- shell (0)
- C (2)
- haskell (49)
- functional (1)
- tool (1)
- gnu (1)
- linux (1)
- kaskell (0)
- svn (0)
- wcf (3)
- android (1)
最新评论
in the previous example, we have discussed the ModuleBuilder, There is a slightly related class that you can use to generate dynamic code.
In this code, we are going to show how to create some assemblies which you can both run and save to a file and load execute again.
the referenced material is AssemblyBuilder class. First and foremost, let's see the code.
class DemoAssemblyBuilder { internal static void Main(string[] args) { // An assembly consists of one or more modules, each of which // contains zero or more types. This code creates a single-module // assembly, the most common case. The module contains one type, // named "MyDynamicType", that has a private field, a property // that gets and sets the private field, constructors that // initialize the private field, and a method that multiplies // a user-supplied number by the private field value and returns // the result. In C# the type might look like this: /* public class MyDynamicType { private int m_number; public MyDynamicType() : this(42) {} public MyDynamicType(int initNumber) { m_number = initNumber; } public int Number { get { return m_number; } set { m_number = value; } } public int MyMethod(int multiplier) { return m_number * multiplier; } } */ AssemblyName aName = new AssemblyName("DynamicAssemblyExample"); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.RunAndSave); // the generated asssembly will both be used to run and saved as some Assembly file for later use // other values include AssemblyBuilderAccess.Run, AssemblyBuilderAccess.Save, AssemblyBuilderAccess.ReflectionOnly, AssemblyBuilderAccess.RunAndCollect // for a single-module assembly, the module name is usually // the assembly name plus an extension ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); // since we are going to save, we have to give it a name TypeBuilder tb = mb.DefineType( "MyDynamicType", TypeAttributes.Public); // Add a private field of type int (Int32) FieldBuilder fbNumber = tb.DefineField( "m_number", typeof(int), FieldAttributes.Private); // private int m_number // Define a constructor that takes an integer argument and // stores it in the private field. Type[] parameterTypes = { typeof(int) }; ConstructorBuilder ctor1 = tb.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, parameterTypes); ILGenerator ctor1IL = ctor1.GetILGenerator(); // For a constructor, argument zero is a reference to the new // instance. Push it on the stack before calling the base // class constructor. Specify the default constructor of the // base class (System.Object) by passing an empty array of // types (Type.EmptyTypes) to GetConstructor. ctor1IL.Emit(OpCodes.Ldarg_0); // for a class method, the first OpCodes.Ldarg_0 is always necessary because it is the 'this' pointer ctor1IL.Emit(OpCodes.Ldarg_1); ctor1IL.Emit(OpCodes.Stfld, fbNumber); ctor1IL.Emit(OpCodes.Ret); // Define a default constructor that supplies a default value // for the private field. For parameter types, pass the empty // array of types or pass null. ConstructorBuilder ctor0 = tb.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator ctor0IL = ctor0.GetILGenerator(); // For a constructor, argument zero is a reference to the new // instance. Push it on the stack before pushing the default // value on the stack, then call constructor ctor1. ctor0IL.Emit(OpCodes.Ldarg_0); ctor0IL.Emit(OpCodes.Ldc_I4_S, 42); // Ldc stands for load constant as Int 4 bytes (short form) onto the stack ctor0IL.Emit(OpCodes.Call, ctor1); // this: this(42) ctor0IL.Emit(OpCodes.Ret); // return // Define a property named Number that gets and sets the private // field. // // The last argument of DefineProperty is null, because the // property has no parameters. (If you don't specify null, you must // specify an array of Type objects. For a parameterless property, // use the built-in array with no elements: Type.EmptyTypes) PropertyBuilder pbNumber = tb.DefineProperty( "Number", PropertyAttributes.HasDefault, // has default, what is the default value? typeof(int), // type is int null ); // The property "set" and property "get" methods require a special // set of attributes. MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // we have the following attribute because we want to assign setter/getter to the code // Define the "get" accessor method for Number. The method returns // an integer and has no arguments. (Note that null could be // used instead of Types.EmptyTypes) MethodBuilder mbNumberGetAccessor = tb.DefineMethod( "get_Number", // MethodAttributes.SpecialName getSetAttr, typeof(int), Type.EmptyTypes); // get_Number(void) ILGenerator numberGetIL = mbNumberGetAccessor.GetILGenerator(); // For an instance property, argument zero is the instance. Load the // instance, then load the private field and return, leaving the // field value on the stack. numberGetIL.Emit(OpCodes.Ldarg_0); numberGetIL.Emit(OpCodes.Ldfld, fbNumber); // register <- addressof fbNumber; numberGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for Number, which has no return // type and takes one argument of type int (Int32). MethodBuilder mbNumberSetAccessor = tb.DefineMethod( "set_Number", getSetAttr, null, // void set_Number(int value) new Type[] { typeof(int) }); ILGenerator numberSetIL = mbNumberSetAccessor.GetILGenerator(); // Load the instance and then the numeric argument, then store the // argument in the field. numberSetIL.Emit(OpCodes.Ldarg_0); numberSetIL.Emit(OpCodes.Ldarg_1); numberSetIL.Emit(OpCodes.Stfld, fbNumber); numberSetIL.Emit(OpCodes.Ret); // Last, map the "get" and "set" accessor methods to the // PropertyBuilder. The property is now complete. pbNumber.SetGetMethod(mbNumberGetAccessor); pbNumber.SetSetMethod(mbNumberSetAccessor); // Define a method that accepts an integer argument and returns // the product of that integer and the private field m_number. This // time, the array of parameter types is created on the fly. MethodBuilder meth = tb.DefineMethod( "MyMethod", MethodAttributes.Public, typeof(int), new Type[] { typeof(int) }); ILGenerator methIL = meth.GetILGenerator(); // To retrieve the private instance field, load the instance it // belongs to (argument zero). After loading the field, load the // argument one and then multiply. Return from the method with // the return value (the product of the two numbers) on the // execution stack. methIL.Emit(OpCodes.Ldarg_0); // it is the caller that push the argument to the stack, so in the function body , we assume that we already have the parameters on stack methIL.Emit(OpCodes.Ldfld, fbNumber); // the OpCodes.Ldflda is to load the address of the field methIL.Emit(OpCodes.Ldarg_1); methIL.Emit(OpCodes.Mul); methIL.Emit(OpCodes.Ret); // Finish the type. Type t = tb.CreateType(); // The following line saves the single-module assembly. This // requires AssemblyBuilderAccess to include Save. You can now // type "ildasm MyDynamicAsm.dll" at the command prompt, and // examine the assembly. You can also write a program that has // a reference to the assembly, and use the MyDynamicType type. // ab.Save(aName.Name + ".dll"); // Because AssemblyBuilderAccess includes Run, the code can be // executed immediately. Start by getting reflection objects for // the method and the property. MethodInfo mi = t.GetMethod("MyMethod"); PropertyInfo pi = t.GetProperty("Number"); // Create an instance of MyDynamicType using the default // display it again. Use null to indicate the property // has no index object o1 = Activator.CreateInstance(t); // Display the value of the property, then change it to 127 and // display it again. Use null to indicate that the property Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null)); pi.SetValue(o1, 127, null); Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null)); // has no index. // Call MyMethod, passing 22, and display the return value, 22 // times 127. Arguments must be passed as an array, even when // there is only one. object[] arguments = { 22 }; Console.WriteLine("o1.MyMethod(22): {0} ", mi.Invoke(o1, arguments)); // Create an instance of MyDynamicType using the constructor // that specifies m_Number. The constructor is identified by // matching the types in the argument array. In this case, // the argument array is created on the fly. Display the // property value. object o2 = Activator.CreateInstance(t, new object[] { 5280 }); Console.WriteLine("o2.Number : {0}", pi.GetValue(o2, null)); } }
so, some summary that we can get from the code above:
- you can generate some .dll on the fly, while you can also save the .dll to a local file. it require high level of persmission to do that operation.
- To declare a Property, you first create a property builder, initialize a special MethodAttributes, and then with MethodBuilder, defines two method, get_Property, and set_Property, bind them to the Property with SetGetMethod and SetSetMethod()...
- You will see a lot of raw IL code, which may/may not have the portable issues.
If you take a look at the generated code then you might be able to find this.
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.1 // Metadata version: v4.0.30319 .assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } .assembly DynamicAssemblyExample { .hash algorithm 0x00008004 .ver 0:0:0:0 } .module DynamicAssemblyExample // MVID: {2F8EC134-454A-4A25-BDB6-53649D2F2973} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY // Image base: 0x00410000 // =============== CLASS MEMBERS DECLARATION =================== .class public auto ansi MyDynamicType extends [mscorlib]System.Object { .field private int32 m_number .method public specialname rtspecialname instance void .ctor(int32 A_1) cil managed { // 代码大小 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: stfld int32 MyDynamicType::m_number IL_0007: ret } // end of method MyDynamicType::.ctor .method public specialname rtspecialname instance void .ctor() cil managed { // 代码大小 12 (0xc) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldc.i4.s 42 IL_0003: nop IL_0004: nop IL_0005: nop IL_0006: call instance void MyDynamicType::.ctor(int32) IL_000b: ret } // end of method MyDynamicType::.ctor .method public hidebysig specialname instance int32 get_Number() cil managed { // 代码大小 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: ldfld int32 MyDynamicType::m_number IL_0006: ret } // end of method MyDynamicType::get_Number .method public hidebysig specialname instance void set_Number(int32 A_1) cil managed { // 代码大小 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: stfld int32 MyDynamicType::m_number IL_0007: ret } // end of method MyDynamicType::set_Number .method public instance int32 MyMethod(int32 A_1) cil managed { // 代码大小 9 (0x9) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldfld int32 MyDynamicType::m_number IL_0006: ldarg.1 IL_0007: mul IL_0008: ret } // end of method MyDynamicType::MyMethod .property int32 Number() { .get instance int32 MyDynamicType::get_Number() .set instance void MyDynamicType::set_Number(int32) } // end of property MyDynamicType::Number } // end of class MyDynamicType // ============================================================= // *********** 反汇编完成 ***********************
发表评论
-
wpf - example to enhance ComboBox for AutoComplete
2014-09-19 15:56 1976first let’s see an example ... -
Investigate and troubleshoot possible memory leak issue of .NET application
2014-07-31 10:42 0Hi All, I would like to sh ... -
C# – CoerceValueCallback合并、替换元数据值
2013-08-05 21:59 1925Topic: C# – CoerceValueCallbac ... -
wpf – ListView交替背景色
2013-07-02 20:56 6551Wpf – Alternate background col ... -
C# - 简单介绍TaskScheduler
2013-06-29 17:18 12038标题: C# - 简单介绍TaskSchedulerTit ... -
c# - Get enum from enum attribute
2013-06-27 21:32 1244DescriptionAttribute gives the ... -
C# - PInvoke, gotchas on the RegisterClassEx and the CreateWindowEx
2013-06-24 13:49 2571I get an exception message li ... -
c# - Use PInvoke to create simple win32 Application
2013-06-24 11:59 10946In this post, .net platform h ... -
c# - Linq's Select method as the Map function
2013-06-19 18:47 1287If you comes from a functiona ... -
c# - Tips of Linq expression Any to determine if a collection is Empty
2013-06-19 18:29 938When you are @ the linq expres ... -
myth buster - typeof accepting array of types not acceptable
2013-06-19 17:17 813I have seen from some book whe ... -
windows - trying to create WIN32 application with PInvoke
2013-06-19 14:34 0While it is stupid to do such ... -
WPF - Setting foreground color of Entire window
2013-06-13 16:00 1918You might as well as I would s ... -
WPF - Enhanced TabControl - TabControlEx aka Prerendering TabControl
2013-06-13 13:12 5330As an opening word, let's che ... -
wpf - ControlTemplate and AddLogicChild/RemoveLogicalChild
2013-06-10 15:42 1185Recently I was trying to debug ... -
c# - P/Invoke, DllImport, Marshal Structures and Type conversions
2013-06-05 15:25 1712P/Invoke as in the following q ... -
c# - A study on the NativeWindow - encapsulate window handle and procedure
2013-06-05 14:40 6091NativeWindow gives you a way t ... -
WCF - Notify server when client connects
2013-06-03 18:19 1221It is sometimes very importan ... -
wcf - Debug to enable Server exception in Fault message
2013-06-03 15:47 1091WCF will be able to send back ... -
c# - determine if a type/object is serialzable
2013-05-30 16:35 867In WCF, primitives type are s ...
相关推荐
eventEmitter.emit('data_received'); } // 绑定 connection 事件处理程序 eventEmitter.on('connection', connectHandler); // 触发 connection 事件 eventEmitter.emit('connection'); console.log("程序...
Managed.Reflection, System.Reflection [.Emit ]的托管替换 Managed.ReflectionManaged.Reflection 是对 System.Reflection 和 System.Reflection.Emit的完全管理的替换。 System.Reflection 不同,它不绑定到
--timestamps <format> emit a timestamp at the start of each output line (using optional format string as per strftime(3)) -d, --debug emit debugging output -v, --version show version information ...
4. 记录日志:调用logger的`emit`方法,传递日志数据,例如`logger.emit('logtag', {'key': 'value'})`。 fluent_logger库的一大特点是支持结构化的日志数据,这使得日志数据更加易读和分析。此外,它还提供了异步...
包括组件定义、props传递、事件通信($emit和$v-on)、自定义指令、插槽等内容。 3. **状态管理**:Vue 2.0引入了Vuex作为官方推荐的状态管理工具,用于集中管理组件间的共享状态。学习Vuex的基本原理、状态、动作、...
- 发送数据:`socket.emit('event-name', data);` - 监听数据:`socket.on('event-name', (res) => { console.log(res); });` 6. **错误处理**:库通常会提供错误处理机制,如连接失败、断线重连等,开发者需要...
4. **Namespace**:命名空间是SocketIO的一个特性,允许在一个SocketIO服务器上创建多个独立的通信通道。每个命名空间可以有不同的事件和逻辑,这样可以在同一个Socket连接上处理不同的数据类型或应用场景。 5. **...
6. **API接口**:Swift Socket.IO客户端提供了丰富的API,如`emit()`用于发送事件,`on()`用于监听事件,以及`disconnect()`用于断开连接等,方便开发者集成到自己的应用中。 7. **错误处理**:客户端还提供了错误...
socketIO.emit('my_request', {'message': 'Hello Server!'}) ``` 在分布式和云原生环境(Cloud Native)中,socketIO-client因其实时性和可扩展性得到了广泛应用。例如,在Zookeeper这样的分布式协调服务中,...
当用户输入消息并发送时,触发`emit`方法将消息发送到服务器。 - **展示聊天记录**:服务器广播的消息会在客户端接收到,更新聊天界面显示最新的聊天记录。 5. **HiChat-master项目分析** "HiChat-master--计网...
MSIL使得开发者能够在运行时动态生成和执行代码,这是通过System.Reflection.Emit命名空间中的类来实现的。本教程将深入探讨如何使用MSIL和Emit API来生成和注入C#代码。 首先,让我们了解Emit API的基本概念。Emit...
相反,C#的`System.Reflection.Emit`命名空间提供了动态生成IL代码的能力,这使得在运行时创建类型和方法成为可能。通过这种方式,我们可以动态地构建一个代理类,该类在内部调用本地库的函数,从而避免了P/Invoke的...
The Watchers in AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 The $watchCollection() Function . . . . . . . . . . . . . . . . . . . . . . . 56 The $apply() Function ...
- Vue2.x中,组件间通信可以通过props、事件($emit/$on)、Vuex状态管理或非父子组件间的Bus(事件总线)。 - Vue3.x增加了提供通信的新方法,如提供和注入(provide/inject)以及使用Context API。 面试中,...
Emit学习之旅是一个深入探索C# Emit技术的教程,它为开发者提供了动态生成IL(Intermediate Language)代码的能力。Emit是.NET Framework的一部分,允许程序员在运行时构建和执行方法,这是实现元编程的重要工具。...
- 解决方案一:One possible solution is ①-----------------------. Although it has the advantage of ②-----------------, there might be a potential drawback ③-----------------. - 解决方案二:Another ...
using namespace QtCharts; private: //曲线 QSplineSeries* line; //绘图变量和坐标 QChart* chart; //发来数据的接收槽函数 private slots: void receive_list(QVector<QPointF> list); 在子.cpp中 line =...
io.emit('message', data); }); }); ``` 3. **客户端集成**:在 HTML 页面中,引入 `socket.io-client` 库,并创建一个 `Socket` 实例,连接到服务器。然后,可以监听服务器发送的事件,以及发送自定义事件。 ...
然后,他们可以调用对象的方法来记录不同级别的日志事件,例如`emit()`方法,同时传递事件的标签和数据。 在分布式和云原生环境中,这种日志记录方案的优势在于它能够集中管理大量节点的日志,方便监控、搜索和分析...
console.log(`Message "${msg}" stored in DB.`); } catch (error) { console.error(error); } io.emit('chat message', msg); }); ``` 这里我们创建了一个名为`messages`的表,用于存储聊天记录。当收到新...