高性能反射初体验2

主要代码 View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Reflection;
  6 using System.Reflection.Emit;
  7 using System.Threading;
  8 
  9 namespace Reflx_Method
 10 {
 11     public class Class1
 12     {
 13         public Class1()
 14         { }
 15       
 16         
 17 
 18       
 19         /// <summary>
 20         /// BeginCatchBlock()用法
 21         /// </summary>
 22         public void ILGenerator_BeginCatchBlock()
 23         {
 24             AppDomain current = AppDomain.CurrentDomain;
 25             AssemblyName myAsmName = new AssemblyName();
 26             myAsmName.Name = "AdderExceptionAsm";
 27             AssemblyBuilder myAsmBldr = current.DefineDynamicAssembly(myAsmName,
 28                                      AssemblyBuilderAccess.RunAndSave);
 29 
 30             ModuleBuilder myModBldr = myAsmBldr.DefineDynamicModule(myAsmName.Name,
 31                                myAsmName.Name + ".dll");
 32             //internal class Adder{
 33 
 34             TypeBuilder myTypeBldr = myModBldr.DefineType("Adder");
 35 
 36             
 37 
 38             // This method will add two numbers which are 100 or less. If either of the 此方法将添加两个数字是100或更少。如果任
 39             // passed integer vales are greater than 100, it will throw an exception. 通过整数山谷大于100 ,它会抛出一个异常
 40         
 41             //  public static int DoAdd(int num1, int num2){
 42             //参数
 43 
 44             Type[] adderParams = new Type[] { typeof(int), typeof(int) };
 45             ///DoAdd方法
 46             MethodBuilder adderBldr = myTypeBldr.DefineMethod("DoAdd",
 47                                MethodAttributes.Public |
 48                                MethodAttributes.Static,
 49                                typeof(int),
 50                                adderParams);
 51 
 52             ILGenerator adderIL = adderBldr.GetILGenerator();
 53 
 54             // Types and methods used in the code to throw, catch, and 抛出,捕捉,在代码中使用的类型和方法
 55             // display OverflowException. Note that if the catch block were 显示引发OverflowException 。请注意,如果catch块
 56             // for a more general type, such as Exception, we would need  更普遍的类型,如异常,我们需要
 57             // a MethodInfo for that type's ToString method.  该类型的ToString方法的MethodInfo 。
 58 
 59             //    OverflowException exception = new OverflowException("Cannot accept values over 100 for add."); throw new OverflowException();
 60             ///
 61             /// <summary>
 62             /// OverflowException异常Type
 63             /// </summary>
 64             Type overflow = typeof(OverflowException);
 65             ConstructorInfo exCtorInfo = overflow.GetConstructor(
 66                               new Type[] { typeof(string) });
 67             //  Console.WriteLine("Caught {0}", exception1.ToString());
 68 
 69             ///OverflowException异常Type的ToString方法
 70             MethodInfo exToStrMI = overflow.GetMethod("ToString");
 71             ///Console对象Type的WriteLine方法
 72             MethodInfo writeLineMI = typeof(Console).GetMethod("WriteLine",
 73                               new Type[] 
 74                         {typeof(string),
 75                          typeof(object)});
 76            // int num;
 77             ///局部变量 int num
 78             LocalBuilder tmp1 = adderIL.DeclareLocal(typeof(int));
 79 
 80             ///OverflowException exception1 异常变量 
 81             LocalBuilder tmp2 = adderIL.DeclareLocal(overflow);
 82 
 83             // In order to successfully branch, we need to create labels  为了成功的分支,我们需要创建标签
 84             // representing the offset IL instruction block to branch to. 代表跳转到偏移的IL指令块。
 85             // These labels, when the MarkLabel(Label) method is invoked, 这些标签的MarkLabel (标签)方法被调用时,
 86             // will specify the IL instruction to branch to.   将跳转到指定的IL指令
 87             // 
 88             ///标签1
 89             Label failed = adderIL.DefineLabel();
 90             ///标签2
 91             Label endOfMthd = adderIL.DefineLabel();
 92 
 93             /// Begin the try block. 开始的try块。  try{ 
 94             Label exBlock = adderIL.BeginExceptionBlock();
 95 
 96           
 97           
 98            
 99             // First, load argument 0 and the integer value of "100" onto the  首先,加载参数0和整数值到“100"
100             adderIL.Emit(OpCodes.Ldarg_0);
101             // stack. If arg0 > 100, branch to the label "failed", which is marked  叠加。如果arg0的> 100,分支标签“失败” ,这标志着
102             adderIL.Emit(OpCodes.Ldc_I4_S, 100);
103             // as the address of the block that throws an exception.  块抛出一个异常的地址
104             adderIL.Emit(OpCodes.Bgt_S, failed);
105 
106 
107 
108             // branching unconditionally to the instruction at the label "endOfMthd". 无条件分支的指令在标签“ endOfMthd ” 。
109            
110             adderIL.Emit(OpCodes.Ldarg_1);
111             // Now, check to see if argument 1 was greater than 100. If it was,  现在,请检查,如果参数1大于100 。如果是,
112             adderIL.Emit(OpCodes.Ldc_I4_S, 100);
113             // branch to "failed." Otherwise, fall through and perform the addition, 分支“失败。 ”否则,属于通过并执行另外,
114             adderIL.Emit(OpCodes.Bgt_S, failed);
115 
116             //参数0
117             adderIL.Emit(OpCodes.Ldarg_0);
118             //参数1
119             adderIL.Emit(OpCodes.Ldarg_1);
120             //无符号相加
121             adderIL.Emit(OpCodes.Add_Ovf_Un);
122             // Store the result of the addition. 存储在另外的结果。
123             adderIL.Emit(OpCodes.Stloc_S, tmp1); 
124 
125             adderIL.Emit(OpCodes.Br_S, endOfMthd);
126 
127             // If one of the arguments was greater than 100, we need to throw an  如果一个参数是大于100 ,我们需要抛出
128             // exception. We'll use "OverflowException" with a customized message. 例外。我们将使用一个定制的消息“引发OverflowException ” 。
129             // First, we load our message onto the stack, and then create a new   首先,我们加载到堆栈上我们的信息,然后创建一个新的
130             // exception object using the constructor overload that accepts a 使用构造函数重载,它接受一个异常对象
131             // string message.  字符串消息
132             // OverflowException exception = new OverflowException("不能接受的增加值超过100 。.");
133 
134             adderIL.MarkLabel(failed);
135             adderIL.Emit(OpCodes.Ldstr, "不能接受的增加值超过100 。");
136             adderIL.Emit(OpCodes.Newobj, exCtorInfo);
137 
138             // We're going to need to refer to that exception object later, so let's 我们要需要参考该异常对象后,让我们
139             // store it in a temporary variable. Since the store function pops the 存储在一个临时变量。由于存储功能弹出
140             // the value/reference off the stack, and we'll need it to throw the 堆栈的值/参考,我们需要它扔
141             // exception, we will subsequently load it back onto the stack as well.例外,我们将随后加载它放回堆栈以及。
142              
143             adderIL.Emit(OpCodes.Stloc_S, tmp2);
144             adderIL.Emit(OpCodes.Ldloc_S, tmp2);
145 
146             // Throw the exception now on the stack. 现在抛出异常堆栈  throw new OverflowException();
147 
148             adderIL.ThrowException(overflow);
149 
150             // Start the catch block for OverflowException.
151             /// 开始为引发OverflowException catch块。 
152             adderIL.BeginCatchBlock(overflow);
153 
154             // When we enter the catch block, the thrown exception    当我们进入catch块,抛出异常
155             // is on the stack. Store it, then load the format string  是在堆栈上。储存,然后加载格式字符串
156             // for WriteLine. 的WriteLine 。
157 
158             //
159             adderIL.Emit(OpCodes.Stloc_S, tmp2);
160             adderIL.Emit(OpCodes.Ldstr, "Caught {0}");
161 
162             // Push the thrown exception back on the stack, then   推抛出的异常堆栈上的背部,然后
163             // call its ToString() method. Note that if this catch block 调用其ToString ()方法。请注意,如果该catch块
164             // were for a more general exception type, like Exception,  为更一般的异常类型,如异常
165             // it would be necessary to use the ToString for that type. 就必须使用这种类型的ToString 。
166             // Console.WriteLine("Caught {0}", exception1.ToString());
167 
168             adderIL.Emit(OpCodes.Ldloc_S, tmp2);
169             adderIL.EmitCall(OpCodes.Callvirt, exToStrMI, null);
170 
171             // The format string and the return value from ToString() are 格式字符串的ToString()的返回值
172             // now on the stack. Call WriteLine(string, object). 现在堆栈。调用的WriteLine (字符串,对象) 。
173             //
174             adderIL.EmitCall(OpCodes.Call, writeLineMI, null);
175 
176             // Since our function has to return an integer value, we'll load -1 onto 因为我们的函数返回一个整型值,我们将载入-1到
177             // the stack to indicate an error, and store it in local variable tmp1. 堆栈显示一个错误,它存储在局部变量TMP1 。
178             // num = -1;
179 
180             adderIL.Emit(OpCodes.Ldc_I4_M1);
181             adderIL.Emit(OpCodes.Stloc_S, tmp1);
182 
183             // End the exception handling block.  num = -1;
184 
185 
186             adderIL.EndExceptionBlock();
187 
188             // The end of the method. If no exception was thrown, the correct value  该方法的结束。如果没有异常被抛出,正确的值
189             // will be saved in tmp1. If an exception was thrown, tmp1 will be equal  将被保存在TMP1 。如果一个异常被抛出, TMP1将等于
190             // to -1. Either way, we'll load the value of tmp1 onto the stack and return. -1。无论哪种方式,我们将加载到堆栈,并返回TMP1价值。
191             // return num;
192 
193             adderIL.MarkLabel(endOfMthd);
194             adderIL.Emit(OpCodes.Ldloc_S, tmp1);
195             adderIL.Emit(OpCodes.Ret);
196 
197            
198 
199             Type adderType = myTypeBldr.CreateType();
200 
201             object addIns = Activator.CreateInstance(adderType);
202 
203             object[] addParams = new object[2];
204 
205             Console.Write("Enter an integer value: ");
206             addParams[0] = (object)Convert.ToInt32(Console.ReadLine());
207 
208             Console.Write("Enter another integer value: ");
209             addParams[1] = (object)Convert.ToInt32(Console.ReadLine());
210 
211             Console.WriteLine("If either integer was > 100, an exception will be thrown.");
212             Console.WriteLine("---");
213 
214             Console.WriteLine("{0} + {1} = {2}",
215                   addParams[0], addParams[1],
216                   adderType.InvokeMember("DoAdd",
217                      BindingFlags.InvokeMethod,
218                      null,
219                      addIns,
220                      addParams));
221             myAsmBldr.Save("AdderExceptionAsm.dll");
222           
223         }
224         
225         /// <summary>
226         /// BeginScope()与EndScope()用法
227         /// </summary>
228         public void ILGenerator_Begin_End_Scope()
229         {
230             // 获取当前AppDomain 。
231 
232             AppDomain myAppDomain = AppDomain.CurrentDomain;
233             AssemblyName myAssemblyName = new AssemblyName();
234             myAssemblyName.Name = "SampleAssembly";
235 
236             // Create a dynamic assembly 'myAssembly' with access mode 'Run'.创建一个动态的组装与访问模式“运行” “ myAssembly的” 。
237 
238             AssemblyBuilder myAssembly = myAppDomain.DefineDynamicAssembly(
239                                     myAssemblyName, AssemblyBuilderAccess.RunAndSave);
240             // Create a dynamic module 'myModule' in 'myAssembly'. 创建一个动态模块myAssembly的“ MyModule的” 。
241 
242             ModuleBuilder myModule = myAssembly.DefineDynamicModule("MyDynamicModule", "MyDynamicModule.dll", true);
243             // Define a public class 'MyDynamicClass'.  定义一个公共类的“ MyDynamicClass ' 。
244 
245             TypeBuilder myTypeBuilder = myModule.DefineType("MyDynamicClass",
246                                              TypeAttributes.Public);
247             // Define a public string field.  定义一个公共的字符串字段。
248 
249             FieldBuilder myField = myTypeBuilder.DefineField("MyDynamicField1",
250                                      typeof(String), FieldAttributes.Public);
251             // Create the constructor.  创建构造。
252 
253             Type[] myConstructorArgs = { typeof(String) };
254             ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor(
255                MethodAttributes.Public, CallingConventions.Standard, myConstructorArgs);
256             ConstructorInfo mySuperConstructor = typeof(Object).GetConstructor(new Type[0]);
257             // Generate IL for 'myConstructor'.  生成IL ' myConstructor “ ”
258 
259             ILGenerator myConstructorIL = myConstructor.GetILGenerator();
260             // Emit the necessary opcodes. 发出了必要的操作码
261 
262             myConstructorIL.Emit(OpCodes.Ldarg_0); 
263             myConstructorIL.Emit(OpCodes.Call, mySuperConstructor);
264             myConstructorIL.Emit(OpCodes.Ldarg_0);
265             myConstructorIL.Emit(OpCodes.Ldarg_1);
266             myConstructorIL.Emit(OpCodes.Stfld, myField);
267             myConstructorIL.Emit(OpCodes.Ret);
268 
269             // Define a dynamic method named 'MyDynamicMethod'.  定义和动态的方法,名为“ MyDynamicMethod
270 
271         
272 
273             
274             MethodBuilder myMethod = myTypeBuilder.DefineMethod("MyDynamicMethod",
275                MethodAttributes.Public | MethodAttributes.SpecialName, typeof(string), Type.EmptyTypes);
276             // Generate IL for 'myMethod'.
277             ILGenerator myMethodIL = myMethod.GetILGenerator();
278 
279             // Begin the scope for a local variable.开始的一个局部变量的范围。
280 
281             myMethodIL.BeginScope();
282 
283             LocalBuilder myLocalBuilder = myMethodIL.DeclareLocal(typeof(int));
284 
285             LocalBuilder shili = myMethodIL.DeclareLocal(typeof(int));
286             Console.WriteLine("\n试图访问的范围内,局部变量.");
287             Console.WriteLine("'myLocalBuilder' type is: {0}", myLocalBuilder.LocalType);
288             myMethodIL.Emit(OpCodes.Ldstr, "Local value");
289             myMethodIL.Emit(OpCodes.Stloc_0, myLocalBuilder);
290 
291             
292              myMethodIL.Emit(OpCodes.Ldstr, "Local value111");
293              myMethodIL.Emit(OpCodes.Stloc_S, shili);
294 
295 
296 
297 
298              Console.WriteLine("\n试图访问的范围内,局部变量.");
299              Console.WriteLine("'myLocalBuilder' type is: {0}", shili.LocalType);
300 
301            
302             // End the scope of 'myLocalBuilder'.
303             myMethodIL.EndScope();
304 
305             // Access the local variable outside the scope.
306             Console.WriteLine("\nTrying to access the local variable outside the scope:");
307             myMethodIL.Emit(OpCodes.Stloc_0, myLocalBuilder);
308             myMethodIL.Emit(OpCodes.Ldloc_S, shili);
309             myMethodIL.Emit(OpCodes.Ret);
310 
311             // Create 'MyDynamicClass' class.
312             Type myType1 = myTypeBuilder.CreateType();
313 
314 
315             myAssembly.Save("MyDynamicModule.dll");
316         }
317 
318 
319        
320 
321         
322 
323 
324     }
325 }

 

调用代码 View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Reflection;
 6 using System.Reflection.Emit;
 7 
 8 namespace Reflx_Method
 9 {
10    
11     class Program
12     {
13        
14         static void Main(string[] args)
15         { 
16             new Class1().ILGenerator_Begin_End_Scope();
17 
18             new Class1().ILGenerator_BeginCatchBlock();
19 
20         }
21          
22     } 
23 
24 }
25  

 

方法ILGenerator_BeginCatchBlock()等效 View Code
 1 public class Adder
 2 {
 3     // Methods
 4     public static int DoAdd(int num1, int num2)
 5     {
 6         int num;
 7         OverflowException exception;
 8         try
 9         {
10             if ((num1 <= 100) && (num2 <= 100))
11             {
12                 return (num1 + num2);
13             }
14             exception = new OverflowException("不能接受超过100的参数");
15             throw new OverflowException();
16         }
17         catch (OverflowException exception2)
18         {
19             Console.WriteLine("捕捉 {0}{1}", exception.ToString(), exception2.ToString());
20             num = -1;
21         }
22         return num;
23     }
24 }
25 
26  

 

方法ILGenerator_Begin_End_Scope()等效 View Code1
 1 public class MyDynamicClass
 2 {
 3     // Fields
 4     public string MyDynamicField1;
 5 
 6     // Methods
 7     public MyDynamicClass(string text1)
 8     {
 9         this.MyDynamicField1 = text1;
10     }
11 
12     public string MyDynamicMethod()
13     {
14         int num2 = "Local value111";
15         return (string) num2;
16     }
17 }
18 
19  

 

 

DEMO

转载于:https://www.cnblogs.com/kubimiantiao/archive/2012/04/18/2455677.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在VC++中实现高性能反射可以通过一些技术和设计模式来实现。下面是一个简单示例,演示了如何使用模板和静态变量来实现基本的高性能反射功能。 ```cpp #include <iostream> #include <unordered_map> #include <functional> // 定义一个基类 class Reflectable { public: virtual void reflect() = 0; }; // 定义一个具体的类 class MyClass : public Reflectable { public: void reflect() override { std::cout << "Reflecting MyClass" << std::endl; } }; // 定义一个反射管理类 class ReflectionManager { public: template<typename T> static void Register() { // 使用类型名称作为键,保存类型的反射函数 registry()[typeid(T).name()] = []() { return new T(); }; } static Reflectable* Create(const std::string& className) { if (registry().find(className) != registry().end()) { // 根据类型名称调用对应的反射函数创建对象 return registry()[className](); } return nullptr; } private: static std::unordered_map<std::string, std::function<Reflectable*()>>& registry() { static std::unordered_map<std::string, std::function<Reflectable*()>> instance; return instance; } }; // 注册具体类 ReflectionManager::Register<MyClass>(); int main() { // 创建对象并调用反射函数 Reflectable* obj = ReflectionManager::Create(typeid(MyClass).name()); if (obj) { obj->reflect(); delete obj; } return 0; } ``` 在上面的示例中,我们定义了一个基类`Reflectable`,它包含一个纯虚函数`reflect()`。然后我们定义了一个具体的类`MyClass`,它继承自`Reflectable`并实现了`reflect()`函数。 然后我们定义了一个`ReflectionManager`类,它包含一个静态的、返回`std::unordered_map<std::string, std::function<Reflectable*()>>`类型的函数`registry()`,用于保存类型名称和反射函数的映射关系。我们使用模板函数`Register()`来注册具体的类,将其类型名称和创建对象的lambda表达式保存到映射关系中。 在主函数中,我们通过调用`ReflectionManager::Create()`函数来创建对象,传入类型名称作为参数。如果找到对应的类型名称,就会调用对应的反射函数创建对象,并调用其`reflect()`函数。 这个示例虽然简单,但展示了一个基本的高性能反射实现。你可以根据实际需求扩展这个示例,例如添加更多的反射信息,支持更多类型的创建等。请注意,这里使用了C++11的特性,所以确保编译器支持C++11标准。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值