标签: il

如何在运行时将IL注入方法

标题或多或少都说明了一切.根据这篇文章,我想出了这个:

public static unsafe void Replace(this MethodBase destination, MethodBase source)
{
    IntPtr srcHandle = source.MethodHandle.GetFunctionPointer();
    IntPtr dstHandle = destination.MethodHandle.GetFunctionPointer();

    int* dstPtr = (int*)dstHandle.ToPointer();
    *dstPtr = srcHandle.ToInt32();
}
Run Code Online (Sandbox Code Playgroud)

这实际上有效...偶尔--.-

例如,这是有效的.

public static class Program
{
    public static void Main(string[] args)
    {
        MethodInfo methodA = typeof(Program).GetMethod("A", BindingFlags.Public | BindingFlags.Static);
        MethodInfo methodB = typeof(Program).GetMethod("B", BindingFlags.Public | BindingFlags.Static);

        methodA.Replace(methodB);

        A();
        B();
    }

    public static void A()
    {
        Console.WriteLine("Hai World");
    }

    public static void B()
    {
        Console.WriteLine("Bai World");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这不是(SEHException).我所做的就是改变定义函数的顺序.

public static …
Run Code Online (Sandbox Code Playgroud)

.net c# il code-injection

8
推荐指数
1
解决办法
4322
查看次数

Delegates比类更轻量级吗?

我试过反汇编一个C#创建的可执行文件,但我无法得出结论.我想知道的是,如果对于CLR c#的委托是真正的特殊实体还是仅仅是编译器糖?

我问这个是因为我正在实现一种编译成C#的语言,而且将匿名函数编译为类而不是代理函数会更有趣.但是我不想使用后来我会后悔的设计,因为它们可能在内存上更重(我想起了Java的PermGen以我的问题为基础.尽管我知道CLR没有这样的东西).

谢谢!

- 编辑

为了更清楚一点,我想知道是否存在(和有什么)之间的区别:

void Main()
{
    Func<int, int, int> add = delegate(int a, int b) {return a + b;};
}
Run Code Online (Sandbox Code Playgroud)

并且,例如

class AnonFuncion__1219023 : Fun3
{
    public override int invoke(int a, int b)
    {
        return a + b;
    }
}
Run Code Online (Sandbox Code Playgroud)

- 编辑

我认为之间可能存在很大差异:

class Program
{
    static int add(int a, int b)
    {
        return a + b;
    }

    static void Main()
    {
        Func<int, int, int> add = Program.add;
    }
}
Run Code Online (Sandbox Code Playgroud)

class Function__432892 : Fun3
{ …
Run Code Online (Sandbox Code Playgroud)

c# clr il delegates internals

8
推荐指数
1
解决办法
474
查看次数

每个.NET类的最大方法数是多少

标题实际上是要求所有,但为了完整起见:

嗨,我正在.NET平台上编写一个小的后编译工具,在尝试优化它时,我遇到了一个问题,我不能轻易找到ECMA标准的公共语言基础结构的答案(CLI).

单个类可以拥有的最大方法数是多少?有限制吗?

编辑:

感谢Kelsey指出真实的测试.虽然我仍然会关心实际限制是什么,但对于我的实际目的,我想知道它是否是2 ^ 16/2 ^ 32 - 或 - 2 ^ 31-1,正如他所指出的,它出现了显然高于每级64K方法..

.net standards il command-line-interface

8
推荐指数
1
解决办法
805
查看次数

高性能克隆

我正在以一种方式深入克隆对象图.我将有多个线程非常快速地克隆图形,以便它们可以在某些状态下播放并丢弃结果,如果它们不感兴趣,则返回到原始状态再次尝试.

我目前正在通过二进制序列化使用深度克隆,尽管它有效但速度并不快.我见过像protobuf这样的其他库,但我的对象图中的类可以在外部程序集中定义,继承自主程序集中的类,并且如果可能的话,不希望在那些使用程序集中添加任何复杂性.

我遇到的一个有趣的事情是使用自动生成的IL进行克隆.它似乎还没有完成,我已发布,看看作者是否已经做了更多,但我猜不是.有没有其他人通过IL开发或看到更全功能的深度克隆方式?或者另一种快速的方法?

c# il clone

8
推荐指数
1
解决办法
1544
查看次数

Debug.Assert是否在发布模式下生成IL?

Debug.Assert()源代码中存在方法调用并且我在发布模式下编译时,编译器是否会生成IL,Debug.Assert()即使它没有被调用?

我们的一位开发人员最近添加了一个Assert,显示有关内部安全性的信息.有人可以查看发布模式IL并找出断言的文本吗?

.net c# il

8
推荐指数
2
解决办法
1073
查看次数

是否有任何IL编辑器来更改程序集的字节码?

我已经检测到遗留第三方程序集上的一些缺陷,我们正在使用我们的代码对它们进行解压缩.我想修复它们但由于我没有源代码,我需要直接修改字节码.这些变化非常简单(为OR更改AND,为某些行更改NOP).

是否有编辑来做这种事情?使用十六进制编辑器进行工作将是最后一个选项,我会想知道我对光标有什么指示......

.net il bytecode disassembly

8
推荐指数
2
解决办法
6918
查看次数

在发布模式下编译silverlight程序集时,IL偏移量丢失

我按照这些说明将IL偏移添加到Silverlight堆栈跟踪.这在DEBUG模式下构建时效果很好但是我们的生产/ qa构建过程使用RELEASE模式编译所有内容,这似乎松散了IL偏移信息.在释放模式下,所有IL偏移最终都是"0xffffffff".使用反射器比较调试/发布程序集我注意到DebuggableAttribute的使用方式不同.

DEBUG构建:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.Default)]
[assembly: AssemblyConfiguration("Debug")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)]
[assembly: Extension]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework("Silverlight,Version=v5.0", FrameworkDisplayName="Silverlight 4")]
[assembly: AssemblyCopyright("Copyright @ Foo Company 2010-2012")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("Foo.Ria.Bar")]
[assembly: AssemblyCompany("Foo Company")]
[assembly: AssemblyProduct("Foo Product")]
Run Code Online (Sandbox Code Playgroud)

vs RELEASE构建:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyTitle("Foo.Ria.Bar")]
[assembly: AssemblyTrademark("")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework("Silverlight,Version=v5.0", FrameworkDisplayName="Silverlight 4")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("Foo Company")] …
Run Code Online (Sandbox Code Playgroud)

.net silverlight il

8
推荐指数
1
解决办法
317
查看次数

使类型的实例不可存储

  • 有没有办法标记一个类型(甚至更好,一个接口),以便它的任何实例都不能存储在一个字段中(以类似的方式TypedReferenceArgIterator?)?
  • 以同样的方式,有没有办法防止实例通过匿名方法传递 - 通常 - 模仿上面两种类型的行为?
  • 这可以通过ILDasm或更一般地通过IL编辑来完成吗?由于UnconstrainedMelody通过编译程序集的二进制编辑实现了通常无法获得的结果,因此可能有一种方法可以通过相同的方法"标记"某些类型(甚至更好的,抽象的或标记接口).

我怀疑它在编译器中是硬编码的,因为错误CS0610文档指出:

有些类型不能用作字段或属性.这些类型包括......

在我看来哪些类型可以扩展 - 但我可能是错的.

我在SO上搜索了一下,虽然我明白以编程方式抛出编译器错误无法完成,但我找不到任何来源说明某些"特殊"类型的行为无法复制.

即使问题主要是学术问题,也可能会有一些答案.例如,有时可以确保某个对象的生命周期被约束到创建它的方法块.

编辑: RuntimeArgumentHandle是一种(未提及)不可存储的类型.

编辑2:如果它可以有任何用途,似乎CLR也以不同的方式处理这些类型,如果不仅仅是编译器(仍然假设类型与其他类型没有任何区别).例如,以下程序将提出一个TypeLoadException问题TypedReference*.我已经对它进行了调整以缩短它,但你可以随心所欲地解决它.例如,void*将指针的类型更改为不会抛出异常.

using System;

unsafe static class Program
{
    static TypedReference* _tr;

    static void Main(string[] args)
    {
        _tr = (TypedReference*) IntPtr.Zero;
    }
}
Run Code Online (Sandbox Code Playgroud)

c# il compiler-errors ildasm

8
推荐指数
1
解决办法
278
查看次数

Conditional属性如何工作?

我有一些标有的辅助方法[Conditional("XXX")].目的是在仅存在XXX条件编译符号时使方法有条件地编译.我们使用它来调试和跟踪功能,它运行良好.

在我研究条件编译如何工作的过程中,我发现有几个来源说明用Conditional属性标记的方法将放在IL中,但是不会执行对方法的调用.

代码如何编译成IL而不执行?如何验证行为实际上是如上所述?我没有对IL做过多少工作,所以我的技能在这个方面都很弱.

.net c# il conditional-compilation .net-4.5

8
推荐指数
2
解决办法
2755
查看次数

为什么使用动态方法设置只读字段会导致此类错误?

strfld如果将其所有者设置为该类并且关闭JIT检查,则可以使用动态方法中的操作码存储在类的只读字段中.一个例子是在这里.然而,这种方法不适用于来自F#的类,即FSharpOption.请分析以下示例:

using Microsoft.FSharp.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

#if true
using MyType = Microsoft.FSharp.Core.FSharpOption<string>;
#else
using MyType = System.Tuple<string>;
#endif

namespace ConsoleApplication27
{
    class Program
    {
        static void Main(string[] args)
        {
            var something = new MyType("test");

            var dynMethod = new DynamicMethod("ChangeField", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), new [] { typeof(MyType) }, typeof(MyType), true);
            var generator = dynMethod.GetILGenerator();
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldstr, "success");
            generator.Emit(OpCodes.Stfld, typeof(MyType).GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)[0]);
            generator.Emit(OpCodes.Ret);

            var …
Run Code Online (Sandbox Code Playgroud)

c# reflection f# il reflection.emit

8
推荐指数
1
解决办法
824
查看次数