标签: il

MSIL问题(基础)

好吧,我们说这个c#代码:

public override void Write(XDRDestination destination)
{
    destination.WriteInt(intValue);
    destination.WriteBool(boolValue);
    destination.WriteFixedString(str1, 100);
    destination.WriteVariableString(str2, 100);
}
Run Code Online (Sandbox Code Playgroud)

IL:

.method public hidebysig virtual instance void 
        Write(class [XDRFramework]XDRFramework.XDRDestination destination) cil managed
{
  // Code size       53 (0x35)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.0
  IL_0002:  call       instance int32 LearnIL.Test1::get_intValue()
  IL_0007:  callvirt   instance void [XDRFramework]XDRFramework.XDRDestination::WriteInt(int32)
  IL_000c:  ldarg.1
  IL_000d:  ldarg.0
  IL_000e:  call       instance bool LearnIL.Test1::get_boolValue()
  IL_0013:  callvirt   instance void [XDRFramework]XDRFramework.XDRDestination::WriteBool(bool)
  IL_0018:  ldarg.1
  IL_0019:  ldarg.0
  IL_001a:  call       instance string LearnIL.Test1::get_str1()
  IL_001f:  ldc.i4.s   100
  IL_0021:  callvirt   instance void [XDRFramework]XDRFramework.XDRDestination::WriteFixedString(string,
                                                                                                 uint32) …
Run Code Online (Sandbox Code Playgroud)

.net c# il cil

5
推荐指数
1
解决办法
1007
查看次数

将对象转换为IL中的特定类?

在我正在制作的DynamicMethod中,我发现了"操作可能会破坏运行时的稳定性"的原因,虽然我很容易修复它,但它给我留下了一个看似简单的问题:

  • 如何将"对象"类型的对象引用转换为特定类型,以便我可以在对象引用上调用该类型的方法?

以下是示例程序.运行此命令时,它将在编译方法时因"操作可能使运行时不稳定"异常而崩溃.

只是通过改变声明为变量的变量的类型TestClass来解决问题Object,但我仍然想知道如何将引用转换为代码中的相应类型.

在代码中我标记了一个带有星号的行.在那一点上我可以发出什么代码来使Object堆栈上的TestClass引用成为引用,以便方法调用将通过?

请注意,我知道这是产生问题的方法调用,如果我完全注释掉这些行,那么变量的类型无关紧要,该方法被编译并执行正常.

这是代码.

using System;
using System.Reflection.Emit;

namespace ConsoleApplication9
{
    public class TestClass
    {
        public void TestMethod() { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(TestClass);
            DynamicMethod method = new DynamicMethod("", typeof(Object), null);
            ILGenerator il = method.GetILGenerator();
            LocalBuilder variable = il.DeclareLocal(typeof(Object));

            // Construct object
            il.Emit(OpCodes.Newobj, type.GetConstructor(new Type[0]));
            il.Emit(OpCodes.Stloc, variable);

            // Call Test method
            il.Emit(OpCodes.Ldloc, variable);
            // ***************************************** what do I do here? …
Run Code Online (Sandbox Code Playgroud)

c# il casting

5
推荐指数
1
解决办法
2865
查看次数

C#if else例外

我试图通过System.Reflection和System.Reflection.Emit使if-else在IL中工作.这是我目前拥有的代码:

Label inequality = new System.Reflection.Emit.Label();
Label equality = new System.Reflection.Emit.Label();
Label end = new System.Reflection.Emit.Label();
var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
var g = method.GetILGenerator();
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Call, typeof(String).GetMethod("op_Equality", new Type[]{typeof(string), typeof(string)}));
g.Emit(OpCodes.Ldc_I4, 0);
g.Emit(OpCodes.Ceq);
g.Emit(OpCodes.Brtrue_S, inequality);
g.MarkLabel(inequality); //HERE it throws exception
g.Emit(OpCodes.Ldstr, "Specified strings are different.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)}));
g.Emit(OpCodes.Br_S, end);
g.Emit(OpCodes.Brfalse_S, equality);
g.MarkLabel(equality);
g.Emit(OpCodes.Ldstr, "Specified strings are same.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
g.Emit(OpCodes.Br_S, end);
g.MarkLabel(end);
g.Emit(OpCodes.Ret);

var action = (Action)method.CreateDelegate(typeof(Action)); …
Run Code Online (Sandbox Code Playgroud)

c# reflection il reflection.emit system.reflection

5
推荐指数
1
解决办法
456
查看次数

在.NET应用程序中查看所有调用的最简单方法(分析/检测)

我正在尝试编写一个.NET应用程序,它可以分析其他.NET进程并列出它们所做的所有调用,包括传递参数的值.

我知道用"ICorProfilerCallback2"之类的东西编写我自己的探查器可以对此有所帮助,但这似乎是一项非常具有挑战性的任务.在进行之前,我想确保这是实现这一目标的唯一方法.

我看着开源.NET剖析和一致好评,如部分覆盖,CLR探查器4.0版等,但他们都不似乎提供了一个管理API来做到这一点,他们做的远远超过我所需要的(内存分析等).

有没有其他方法可以做到这一点?一种更简单的方法来进行这种分析?我在这里有什么选择?

.net instrumentation il profiling

5
推荐指数
1
解决办法
323
查看次数

如何调试动态生成的方法?

我有一个动态创建的程序集,一个模块,一个类和一个动态生成的方法。

AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(...);
ModuleBuilder module = assembly.DefineDynamicModule(...);
TypeBuilder tb = module.DefineType(...);
MethodBuilder mb = tb.DefineMethod(...);
ILGenerator gen = mb.GetILGenerator();
Run Code Online (Sandbox Code Playgroud)

如何调试使用生成的方法代码ILGenerator?我使用Visual Studio 2012调试器,但它只是逐步执行方法调用。

.net debugging il dynamic visual-studio-2012

5
推荐指数
1
解决办法
1110
查看次数

IL的"短"符号的目的是什么?

每次我在IL中使用它们:br_S,ldc_i4_S,ldarg_S等等......所以我只需要问这个问题:

我的意思是......如果你是从IL到本地汇编程序的JIT语言,它在性能方面应该不重要,对吧?那么这些"短手"符号的目的是什么?是仅仅因为IL二进制文件中的字节数较少(例如作为压缩机制)还是有其他原因?

如果它只是一个压缩机制,为什么不使用压缩算法,如deflate?

.net c# il opcode

5
推荐指数
2
解决办法
548
查看次数

由于一些无效的IL代码,将简单类转换为IL失败了?

我正在尝试将这个简单的类转换为IL代码:

public class IL {
  Dictionary<string, int> props = new Dictionary<string, int>() { {"1",1} };
}
Run Code Online (Sandbox Code Playgroud)

事实上,ILDasm在尝试使用Emit动态创建类之前,我曾经知道IL指令.结果显示:

.class public auto ansi beforefieldinit IL
   extends [mscorlib]System.Object
{
 .field private class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> props
 .method public hidebysig specialname rtspecialname 
      instance void  .ctor() cil managed
 {
 // 
 .maxstack  4
 .locals init (class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> V_0)
 IL_0000:  ldarg.0
 IL_0001:  newobj     instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::.ctor()
 IL_0006:  stloc.0
 IL_0007:  ldloc.0
 IL_0008:  ldstr      "1"
 IL_000d:  ldc.i4.1
 IL_000e:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
                                                                                                              !1)
 IL_0013:  ldloc.0 …
Run Code Online (Sandbox Code Playgroud)

c# reflection il reflection.emit dynamic

5
推荐指数
1
解决办法
165
查看次数

CIL unbox_any指令 - 奇怪的行为

.method public static void  Test<class T>(object A_0) cil managed
{
  // Code size       13 (0xd)
  .maxstack  1
  .locals init (!!T V_0)
  IL_0000:  ldarg.0
  IL_0001:  isinst     !!T
  IL_0006:  unbox.any  !!T
  IL_000b:  stloc.0
  IL_000c:  ret
} // end of method DemoType::Test
Run Code Online (Sandbox Code Playgroud)

相同的C#代码是:

public static void Test<T>(object o) where T : class
{
    T t = o as T;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么unbox.any被称为?如果你这样做

     var a = father as child 
    
    Run Code Online (Sandbox Code Playgroud)

    isinst intruction将调用而不是unbox.any,如果我将删除泛型定义并且我将尝试将(isinst)对象强制转换为某个类,则不会调用unbox.any.

  2. 也许因为泛型定义而调用unbox.any,所以在这种情况下unbox.any需要抛出NullReferenceException,因为isinst指令的答案为此转换返回null.请参阅unbox_any.如果您尝试运行此代码,您将看到没有抛出任何异常.

更新

我可以理解unbox_any因为对象类型参数,它尝试在isinst检查后将其强制转换为具体类型.也许仿制药也会影响.

我的问题是,为什么不在unbox.any中抛出异常,如果我们尝试unbox到T的obj是null?

文档说:"如果obj是一个空引用,则抛出NullReferenceException."

.net clr il cil nullreferenceexception

5
推荐指数
1
解决办法
258
查看次数

调用非指定类的方法

我怀疑这两个方面;

第一;

        Test test = new Test();

        result = test.DoWork(_param);
Run Code Online (Sandbox Code Playgroud)

第二个;

       result = new Test().DoWork(_param);
Run Code Online (Sandbox Code Playgroud)

如果我们不将新创建的实例分配给变量并直接调用该方法会发生什么?

我看到IL代码的两种方式有所不同.


下面这个是第一个c#代码的IL输出

 IL_0000:  ldstr      "job "
 IL_0005:  stloc.0
 IL_0006:  newobj     instance void Works.Test::.ctor()
 IL_000b:  stloc.1
 IL_000c:  ldloc.1
 IL_000d:  ldloc.0
 IL_000e:  callvirt   instance string Works.Test::DoWork(string)
 IL_0013:  pop
 IL_0014:  ret
Run Code Online (Sandbox Code Playgroud)

这个是第二个c#代码的IL输出

 IL_0000:  ldstr      "job "
 IL_0005:  stloc.0
 IL_0006:  newobj     instance void Works.Test::.ctor()
 IL_000b:  ldloc.0
 IL_000c:  call       instance string Works.Test::DoWork(string)
 IL_0011:  pop
 IL_0012:  ret
Run Code Online (Sandbox Code Playgroud)

你能告诉我吗?

c# oop il

5
推荐指数
1
解决办法
251
查看次数

Fody Async MethodDecorator处理异常

我试图使用Fody来包装从具有常见异常格式的方法抛出的所有异常.

所以我添加了所需的接口声明和类实现,如下所示:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;

[module: MethodDecorator]

public interface IMethodDecorator
{
  void Init(object instance, MethodBase method, object[] args);
  void OnEntry();
  void OnExit();
  void OnException(Exception exception);
  void OnTaskContinuation(Task t);
}


[AttributeUsage(
    AttributeTargets.Module |
    AttributeTargets.Method |
    AttributeTargets.Assembly |
    AttributeTargets.Constructor, AllowMultiple = true)]
public class MethodDecorator : Attribute, IMethodDecorator
{
  public virtual void Init(object instance, MethodBase method, object[] args) { }

  public void OnEntry()
  {
    Debug.WriteLine("base on entry");
  }

  public virtual void OnException(Exception exception)
  {
    Debug.WriteLine("base on exception"); …
Run Code Online (Sandbox Code Playgroud)

c# il asynchronous fody

5
推荐指数
1
解决办法
1321
查看次数