是否可以在函数执行过程中设置指向当前堆栈的指针(稍后获取)然后释放当前线程(不解除调用堆栈)并将其返回给线程池?然后,让另一个线程在该线程停止的地方继续?我知道这意味着调用函数的人不会知道当前的线程上下文会发生变化,并且可能会涉及编写一些自定义的IL代码来做这样的事情,但有没有办法做到这一点?
我正在尝试解析IL,以发出一种方法。我已经在string []中获得了方法的IL代码,其中每个字符串都是IL指令。我遍历此数组并使用ILGenerator添加OpCodes:
foreach (string ins in instructions) //string representations of IL
{
string opCode = ins.Split(':').ElementAt(1);
// other conditions omitted
if (opCode.Contains("br.s"))
{
Label targetInstruction = ilGenerator.DefineLabel();
ilGenerator.MarkLabel(targetInstruction);
ilGenerator.Emit(OpCodes.Br_S, targetInstruction);
}
Run Code Online (Sandbox Code Playgroud)
这是我需要重现的IL:
Source IL:
IL_0000: nop
IL_0001: ldstr "Hello, World!"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出:
Target IL:
IL_0000: nop
IL_0001: ldstr "Hello, World!"
IL_0006: stloc.0
IL_0007: br.s IL_0007 // this is wrong -- needs to point to IL_0009
IL_0009: ldloc.0
IL_000a: ret
Run Code Online (Sandbox Code Playgroud)
如您所见,br.s调用指向自身,这当然会导致无限循环。如何获得源代码中的以下说明?这与使用Reflection.Emit.Label有关,但是我不确定它是如何工作的。
编辑通过上面看到的IL就是这种简单方法, …
对不起文字的墙,但我想提供一个很好的背景情况.我知道你可以在IL中调用null引用的方法,但是在你理解CLR的工作方式时,仍然不会理解一些非常奇怪的事情.我在这里找到的关于这一点的其他几个问题并没有涵盖我在这里看到的行为.
这是一些IL:
.assembly MrSandbox {}
.class private MrSandbox.AClass {
.field private int32 myField
.method public int32 GetAnInt() cil managed {
.maxstack 1
.locals init ([0] int32 retval)
ldc.i4.3
stloc retval
ldloc retval
ret
}
.method public int32 GetAnotherInt() cil managed {
.maxstack 1
.locals init ([0] int32 retval)
ldarg.0
ldfld int32 MrSandbox.AClass::myField
stloc retval
ldloc retval
ret
}
}
.class private MrSandbox.Program {
.method private static void Main(string[] args) cil managed {
.entrypoint
.maxstack 1
.locals init ([0] class MrSandbox.AClass …Run Code Online (Sandbox Code Playgroud) 我在代码的各个地方都看过这个术语,比如图形编程样本.它似乎是一个C++语义,但显然有一个名为EmitCalli的C#/ .NET托管实现似乎与OpCodes.Calli有关.我认为这是一种机器语言指令.这个术语的解释是否与外行人的术语有些接近?
我正在使用C#进行一些加密.我想隐藏我的密钥并想到嵌入式资源.我不确定黑客是否可以使用IL反汇编程序获取它.
我正在编写ILAsm函数,它接收可变数量的参数并返回它们的总和:
.class public auto ansi TestSentinel
{
.method public static vararg unsigned int64 Sum( /* all arguments are optional */ )
{
.locals init( value class [mscorlib]System.ArgIterator Args,
unsigned int64 Sum,
int32 NumArgs )
...
ldloc Sum
ret
}
}
Run Code Online (Sandbox Code Playgroud)
我的DLL编译成功但我不能用C#代码调用这个函数.我打电话的时候
var k = TestSentinel.Sum(1);
Run Code Online (Sandbox Code Playgroud)
我收到错误消息:
Error The best overloaded method match for 'TestSentinel.Sum(__arglist, ...)' has some invalid arguments
Run Code Online (Sandbox Code Playgroud)
我收到任何其他数量的论据wrong argument number.调用我的ILAsm函数的正确方法是什么?
我已经在调试模式下编译了一些测试代码,并用ILSpy反映了生成的程序集.这是我得到的IL:
.class private auto ansi beforefieldinit ArrayListBoxAndUnBox.Program
extends [mscorlib]System.Object
{
// Nested Types
.class nested public auto ansi beforefieldinit Point
extends [mscorlib]System.Object
{
// Fields
.field public int32 x
.field public int32 y
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x209f
// 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 Point::.ctor
} // end of class …Run Code Online (Sandbox Code Playgroud) Red Gate Ant Profiler或Reflector等工具如何将IL转换为C#或VB.NET代码?
我最近注意到Red Gate Ant Profiler不生成与最初编写的源代码相同的源代码.
它产生了一个while我用过的循环foreach.
这让我想到了.我在Reflector中打开了Reflector.exe,但是他们的代码大多数(并非全部)都是混淆的.
我正在审查将COBOL代码迁移到.NET运行时的解决方案.我在网上找到的两个最有前途的解决方案是NetCOBOL和Micro Focus Visual COBOL.
NetCOBOL直接编译到MSIL并具有Visual Studio集成.通过"直接编译",我的意思是发出的MSIL代表COBOL代码中的实际调用.这与一种方法形成对比,在该方法中,MSIL代码将对COBOL代码执行词法分析,然后解释/执行它.
Micro Focus Visual COBOL肯定有Visual Studio集成,但我无法在网站上找到关于COBOL代码是直接编译到MSIL还是由解释器处理的明确答案.
我不确定我在这里使用的语义是否100%准确,但我对如何更清楚地表达"直接编译"的发出代码与"解释"的发出代码之间的区别持开放态度.
鉴于以下自动属性:
public string Name { get; set; }
我使用ILDASM分析它的IL,并对结果感到好奇:
.method public hidebysig specialname instance void
set_Name(string 'value') cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld string Strings.Person::'<Name>k__BackingField'
IL_0007: ret
} // end of method Person::set_Name
Run Code Online (Sandbox Code Playgroud)
我可以看到该方法接受一个名为的参数value,该参数对应于该调用ldarg.0.然而,ldarg.1由于我无法在方法签名中看到第二个参数,因此调用了我.
希望有人能解释一下这里发生了什么吗?