标签: dynamicmethod

动态装配和方法

我已经编写了.NET和C#多年,但最近才DynamicMethod在反射的上下文中遇到了类型和动态汇编的概念.它们似乎总是在IL(运行时代码)生成中使用.

不幸的是,MSDN在定义动态汇编/方法属性以及它们应该用于什么方面做得非常糟糕.能不能在这里启发我吗?与DLR有什么关系吗?它们如何与运行时静态(正常)生成的程序集和方法不同?我应该知道如何以及何时使用它们?

.net c# reflection dynamicmethod dynamic-assemblies

7
推荐指数
1
解决办法
1582
查看次数

如何将多个表达式组合成一个快速方法?

假设我有以下表达式:

Expression<Action<T, StringBuilder>> expr1 = (t, sb) => sb.Append(t.Name);
Expression<Action<T, StringBuilder>> expr2 = (t, sb) => sb.Append(", ");
Expression<Action<T, StringBuilder>> expr3 = (t, sb) => sb.Append(t.Description);
Run Code Online (Sandbox Code Playgroud)

我希望能够将这些编译成与以下内容等效的方法/委托:

void Method(T t, StringBuilder sb) 
{
    sb.Append(t.Name);
    sb.Append(", ");
    sb.Append(t.Description);
}
Run Code Online (Sandbox Code Playgroud)

解决这个问题的最佳方法是什么?我希望它表现良好,理想情况下性能与上述方法相当.

更新 所以,虽然似乎没有办法在C#3中直接执行此操作,有没有办法将表达式转换为IL,以便我可以将它与System.Reflection.Emit一起使用?

c# linq lambda dynamicmethod

6
推荐指数
1
解决办法
1115
查看次数

将DynamicMethod保存到磁盘

我继承了使用DynamicMethod在运行时生成方法的代码.我还需要修改一些正在生成的代码.

因为我是MSIL的n00b,所以我希望能够在Reflector中加载生成的代码,并确保代码执行我祈祷的功能;)

只是,我无法弄清楚如何将"Anonymousously Hosted DynamicMethods Assembly"序列化到磁盘.这可能吗?如果是这样,怎么样?

.net cil dynamicmethod

6
推荐指数
2
解决办法
1276
查看次数

ILGenerator:如何使用非托管指针?(我得到VerificationException)

我正在制作一个声音合成程序,用户可以创建自己的声音进行基于节点的合成,创建振荡器,滤波器等...

程序将节点编译成中间语言,然后通过ILGenerator和DynamicMethod转换为MSIL.

它适用于存储所有操作和数据的数组,但如果我能够使用指针允许我稍后执行一些位级操作,它会更快

PD:速度非常重要!!

我注意到一个DynamicMethod构造函数覆盖有一个方法属性,一个是UnsafeExport,但我不能使用它,因为唯一有效的组合是Public + Static

这就是我想要做的事情,它会抛出一个VerificationException :(只是为指针赋值)

//Testing delegate
unsafe delegate float TestDelegate(float* data);

//Inside the test method (wich is marked as unsafe) 

        Type ReturnType = typeof(float);
        Type[] Args = new Type[] { typeof(float*) };

        //Can't use UnamangedExport as method atribute:
        DynamicMethod M = new DynamicMethod(
            "HiThere",
            ReturnType, Args);

        ILGenerator Gen = M.GetILGenerator();

        //Set the pointer value to 7.0:
        Gen.Emit(OpCodes.Ldarg_0);
        Gen.Emit(OpCodes.Ldc_R4, 7F);
        Gen.Emit(OpCodes.Stind_R4);

        //Just return a dummy value:
        Gen.Emit(OpCodes.Ldc_R4, 20F);
        Gen.Emit(OpCodes.Ret);



        var del = (TestDelegate)M.CreateDelegate(typeof(TestDelegate));

        float* data = …
Run Code Online (Sandbox Code Playgroud)

c# pointers unsafe ilgenerator dynamicmethod

6
推荐指数
1
解决办法
552
查看次数

如何在DynamicMethod的emited代码上调试InvalidProgramException

在搜索了stackoverflow和googling很多之后,为DynamicMethods调试代码提供的调试解决方案似乎已经过时且非常笨拙.

当然,在LCG(轻量级代码生成)发布后的4年或更长时间内,有人必须找到更好的方法.

您发现什么是验证您编写和调试它的动态IL的最简单方法?

你使用peverify或ILDasm还是别的什么?这两个工具需要将程序集写入磁盘,但DynamicMethod不提供任何直接的方法.

显然,WinDbg aso提供了一种查看IL的方法,但处理这个问题非常尴尬.

像VisualStudio 2010这样的插件将是理想的选择.

有任何想法吗?

c# debugging reflection.emit dynamicmethod

6
推荐指数
1
解决办法
282
查看次数

通过DynamicMethod调用varargs方法

我正在尝试使用DynamicMethod调用非托管类似printf的函数.在运行时我得到一个

BadImageFormatException:找不到索引.(HRESULT异常:0x80131124)

这是运行时的限制还是我的发出代码错了?

public class Program
{
    [DllImport("msvcrt40.dll",CallingConvention = CallingConvention.Cdecl)]
    public static extern int printf(string format, __arglist);

    static void Main(string[] args) {

        var method = new DynamicMethod("printf", typeof(void), new Type[0], true);
        var il = method.GetILGenerator();

        il.Emit(OpCodes.Ldstr, " %s=%d\n");
        il.Emit(OpCodes.Ldstr, "a");
        il.Emit(OpCodes.Ldc_I4_0);
        il.EmitCall(OpCodes.Call, typeof(Program).GetMethod("printf", BindingFlags.Public | BindingFlags.Static), new Type[] { typeof(string), typeof(int) });
        il.Emit(OpCodes.Pop);
        il.Emit(OpCodes.Ret);

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

c# cil reflection.emit .net-4.0 dynamicmethod

6
推荐指数
1
解决办法
611
查看次数

CIL中的字符串构建器(MSIL)

我正在尝试生成带有StringBuilder的代码,并将类中所有属性的值写入字符串.我有以下内容,但我目前在以下代码中获得了"无效方法令牌":

    public static DynamicAccessor<T> CreateWriter(T target) //Target class to *serialize*
    {
        DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>();

        MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder

        var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true);
        var generator = method.GetILGenerator();
        LocalBuilder sb = generator.DeclareLocal(typeof(StringBuilder)); //sb pointer


        generator.Emit(OpCodes.Newobj, typeof(StringBuilder)); //make our string builder 
        generator.Emit(OpCodes.Stloc, sb);                     //make a pointer to our new sb


        //iterate through all the instance of T's props and sb.Append their values.
        PropertyInfo[] props = …
Run Code Online (Sandbox Code Playgroud)

c# cil token dynamicmethod

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

通过动态方法解析IL中发现的令牌

感谢Hans Passant在这里回答我的问题: 如何从DynamicMethod获取IL bytearray?

我能够起床和跑步.我现在正在尝试解决在IL发出的元数据令牌,以查看正在调用哪些方法,或者什么不是.我能够解决方法体中的下一个标记是一个调用.我正在使用来自Mono.ReflectionMethodBodyReader的一些代码.

static byte[] GetILByteArray(Delegate @delegate){
   // does stuff mentioned in other thread
}
...
Expression<Action> foo = () => Console.WriteLine(0);
var compiled = foo.Compile();
var bytes = GetILByteArray(compiled);
int index =Array.FindIndex(bytes,b=>GetOpCode(b).OperandType == OperandType.InlineMethod);
var token = BitConverter.ToInt32(bytes,index+1);
compiled.Method.Module.ResolveMember(token);
Run Code Online (Sandbox Code Playgroud)

引发异常,说明该域中的令牌是不可解析的.这里有人有诀窍吗?我应该尝试传递代理通用参数还是完全没用?

我现在正在考虑为表达式树的代表编写一个反编译器的想法,我真的希望能够使用我自己编译为测试用例的表达式树,因为我总是可以回到原始版本并进行比较.

c# dynamicmethod

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

使用DynamicMethod注入运行时代码?

请考虑以下简单代码:

using System;   
class Test
{
    delegate int FooDelegate(int i);
    FooDelegate Foo = FooImplementation;
    static int FooImplementation(int i)
    {
        return i + 1;
    }

    public static void Main()
    {
         Foo(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想做的是将一些调试代码注入到Foo委托中,这相当于:

FooDelegate Foo = delegate(int i)
{
    try
    {
        DebugPrologue();
        return FooImplementation(i);
    }
    finally
    {
        DebugEpilogue();
    }
};
Run Code Online (Sandbox Code Playgroud)

扭曲的是我必须能够在运行时执行此操作,因此编译时和后处理方法是不可能的.

我的初始方法使用Delegate.Combine()将序言和结尾方法添加到Foo委托.唉,这不会起作用,因为它会回报价值.

我目前的想法是使用System.Reflection.Emit和DynamicMethod作为潜在的解决方案.据我所知,我需要为FooImplementation获取MethodInfo,获取它的MethodBody,将其转换为DynamicMethod并将try-finally块注入其中.

不幸的是,我完全不知道该怎么做.谁愿意伸出援助之手?或者你有另一个(最好更简单)的想法?

编辑:这里的用例是调试OpenGL绑定(http://www.opentk.com).我们必须注入2226种具有完全不同参数的方法,因此需要采用一般方法.

c# reflection.emit code-injection dynamicmethod opentk

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

简单生成的MSIL抛出"操作可能破坏运行时的稳定性"

我创建了一个非常简单的函数,它执行以下操作:

    public static object[] ToArray(int ID) {
        return new object[4];
    }
Run Code Online (Sandbox Code Playgroud)

这是生成MSIL的代码.为什么这会引发"操作可能破坏运行时的稳定性"异常?我无法发现任何错误; 它完美匹配Reflector/Reflexil中的组件.

    // create method
    Type arrayType = typeof(object[]);
    Type intType = typeof(int);
    DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
    ILGenerator il = dm.GetILGenerator();

    // create the array -- object[]
    il.Emit(OpCodes.Ldc_I4, 4);
    il.Emit(OpCodes.Newarr, typeof(object));
    il.Emit(OpCodes.Stloc_0);

    // return the array
    il.Emit(OpCodes.Ldloc_0); 
    il.Emit(OpCodes.Ret);

    return dm;
    object result = dm.Invoke(null, new object[] { 1 });
Run Code Online (Sandbox Code Playgroud)

.net c# cil dynamicmethod

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