Tag: il

动态IL方法导致“操作可能破坏运行时的稳定性”

System.Security.VerificationException:操作可能会破坏运行时的稳定性。 在Connance.CommunicatorApi.ReportApiClient.AcknowledgeRecallsAsyncDynamicHandler(Object,AcknowledgeRecallsCompletedEventArgs) 那是我得到的错误。 我正在尝试做的(背景)是为一类方法创建一个全局事件处理程序。 我正在使用WCF中的静态代理,我需要创建一个跟踪所有调用并返回所有WCF Web方法的层。 不幸的是,WCF强烈地键入了“已完成”事件的EventArgs,几乎不可能。 我决定尝试一下。 如果事件是EventHandler ,我仍然可以注册签名void Method(object, object)来处理事件。 大。 所以我开始创建一个DynamicMethod ,它将调用我的全局处理程序,并将其注册到每个事件。 我试过两种方法: 1)DynamicMethod的类型为void(对象,对象) 2)类型为void(object,SomeSpecificEventArgs) – 我使用generics方法来获取类型。 只有当我尝试手动或为事件调用方法时,我才得到上述exception。 这是我的代码: // The handler for all callbacks. // in the example it does nothing. public void Handler(object sender, object e) { dynamic evtArgs = e; object userState = evtArgs.UserState; } private string GetIdentifier(Delegate d) […]

为2Darrays生成IL

我想使用System.Reflection.Emit命名空间为2D数组构造生成IL。 我的C#代码是 Array 2dArr = Array.CreateInstance(typeof(int),100,100); 使用ildasm ,我意识到为上面的C#代码生成了以下IL代码。 IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_000b: ldc.i4.s 100 IL_000d: ldc.i4.s 100 IL_000f: call class [mscorlib]System.Array [mscorlib]System.Array::CreateInstance(class [mscorlib]System.Type, int32, int32) 我能够生成最后三个IL语句,如下所示。 MethodInfo createArray = typeof(Array).GetMethod(“CreateInstance”, new Type[] { typeof(Type),typeof(int),typeof(int) }); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Call, createArray); 但我不清楚如何生成拳头IL语句(即IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle )) 你有什么主意吗? 此外,有人能指出一些关于如何使用System.Reflection.Emit命名空间以生成IL代码的好教程/文档吗?

IL中“specialname”和“rtspecialname”的目的和意义

我现在特别想了解IL代码和C#内部,我写了一个简单的c#hello world程序,代码是: using System; class Program { public static void Main() { Console.WriteLine(“Hello World”); } } 这里是为Program类的constuctor生成的IL: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Program::.ctor 我无法理解specialname和rtspecialname的含义和目的是什么或者它们的用途是什么?

ldstr在内部实现newobj吗?

众所周知,字符串是隐式实例化的,这意味着我们不必使用new来获取对象的对象的引用。 因此,我始终相信框架正在处理这个问题,因此如果我做了类似的事情,我会得到相同的IL: String first = new String(new char[] {‘a’}); string second = “a”; 然而,似乎第一行是使用newobj instance void [mscorlib]System.String::.ctor(char[])和第二行ldstr “a” 。 所以为了获得一个字符串引用, ldstr内部调用newobj ,在哪里可以看到规范/细节来支持它?

为什么C#编译器会生成方法调用以在IL中调用BaseClass方法

让我们说我们在C#中有以下示例代码: class BaseClass { public virtual void HelloWorld() { Console.WriteLine(“Hello Tarik”); } } class DerivedClass : BaseClass { public override void HelloWorld() { base.HelloWorld(); } } class Program { static void Main(string[] args) { DerivedClass derived = new DerivedClass(); derived.HelloWorld(); } } 当我ildasmed以下代码时: .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // […]

为什么在这种情况下使用’br.s’IL操作码?

出于教育目的,我正在学习一些IL(主要是因为我很好奇发生了什么’%’在幕后(原来是rem)并开始离题……)。 我写了一个方法,只是返回true来解决一些问题并且想知道’br.s’操作码: .method public hidebysig static bool ReturnTrue() cil managed { // Code size 7 (0x7) .maxstack 1 .locals init ([0] bool CS$1$0000) IL_0000: nop IL_0001: ldc.i4.1 IL_0002: stloc.0 IL_0003: br.s IL_0005 IL_0005: ldloc.0 IL_0006: ret } // End of method Primes::ReturnTrue 在ldc.i4.1在堆栈上推送1并且stloc.0将其放在第0个本地之后,br.s基本上(据我所知)在行IL_0005处对ldloc.0执行’goto’。 为什么是这样? 为什么没有IL_0004线,所以这可以省略?

如何理解类名添加符号?

如何在C#中理解这段代码? using System; internal class { } 类名不能包含符号但允许在代码中包含它? 你会如何实现这一目标? 我怎么能理解这种差异呢? 看看这段代码: internal class {D8BAC701-C957-4CBE-8F97-37BB3A7DAFFE} { static {D8BAC701-C957-4CBE-8F97-37BB3A7DAFFE}() { if (!(eqXmHMg8VVPy3nYeAo.eHiMp4DL8(Convert.ToBase64String(Type.GetTypeFromHandle(epOl6XynGueNUNwY5Y.e53w34m968awCm9P85taUZe(33554477)).Assembly.GetName().GetPublicKeyToken()), “eObc8gibn”) != “34NavQ/3DsKjaKpYVSNSMjtuaXO9zUZlQl7AY+p3wrM=”)) { return; } while (true) { eqXmHMg8VVPy3nYeAo.ce4DmfsmSrOT856tDgfrkMb(); } } } 这个类甚至没有命名空间。 我用ILSpy反编译了这个DLL。 但是,我如何使用此代码并对其进行反模糊处理?

基于反汇编简单C#代码的手工编码IL的问题

我刚开始看一下IL,我很好奇我的尝试(如下所示)从编译器的输出中删除多余的代码有任何意想不到的副作用。 关于结果的几个问题: 原始操作中nop操作的目的是什么? 原始方法结束时br.s的目的是什么? 重写版本是否以任何方式不正确? 原始C#代码: class Program { public static int Main() { return Add(1, 2); } public static int Add(int a, int b) { return a + b; } } 用csc.exe编译并用ildasm.exe (原始版本)反汇编: .method public hidebysig static int32 Main() cil managed { .entrypoint .maxstack 2 .locals init (int32 V_0) IL_0000: nop IL_0001: ldc.i4.1 IL_0002: […]

如果新的c#6“?”null检查,则调用而不是callvirt

鉴于这两种方法: static void M1(Person p) { if (p != null) { var p1 = p.Name; } } static void M2(Person p) { var p1 = p?.Name; } 为什么M1 IL代码使用callvirt : IL_0007: brfalse.s IL_0012 IL_0009: nop IL_000a: ldarg.0 IL_000b: callvirt instance string ConsoleApplication4.Person::get_Name() 和M2 IL使用call : brtrue.s IL_0007 IL_0004: ldnull IL_0005: br.s IL_000d IL_0007: ldarg.0 IL_0008: […]

Windows 7 64位中的递归

我有这个助手类 public static class DateTimeHelper { public static int GetMonthDiffrence(DateTime date1, DateTime date2) { if (date1 > date2) { return getmonthdiffrence(date2, date1); } else { return ((date2.year – date1.year) * 12) + (date2.month – date1.month); } } } 该函数计算两个日期之间的月数,它完全符合我的要求。 到目前为止没有问题。 问题是当我在发布时,Windows 7 64位我总是得到相同的值“0” 当我深入研究这个问题时,我意识到在某些时候,由于递归调用,两个参数是相等的。 我再说一遍,我有这个bug,只有当我在发布时没有附加到调试器和Windows 7 64位上。 任何人都可以对这种竞争有任何想法吗? 如果是这样,我需要一些链接来获取更多细节。 这是IL代码。 (我认为它可以帮助理解更多) .class public auto ansi […]