C# 如何获取stackframe的执行对象?
使用反射时,可以使用System.Diagnostics.StackTrace获得调用堆栈(除此之外,由于JIT优化,调用堆栈可能是粗略的近似值),并检查包含的StackFrame对象 如何获取对堆栈帧中的方法正在其上执行的对象(this指针)的引用 我知道我可以通过调用stack frame对象上的GetMethod()来获得MethodBase,但我要寻找的是与GetObject()类似的东西(如果方法是静态的,它自然会返回null)。似乎堆栈帧对象只能查询静态确定的信息,如方法信息、原始文件等 VS调试器知道(尽管它可能使用另一种获取调用堆栈跟踪的方法),因为可以双击调用堆栈窗口中的任何堆栈帧并查看局部变量和类字段的值 编辑:C# 如何获取stackframe的执行对象?,c#,reflection,stack-trace,stack-frame,C#,Reflection,Stack Trace,Stack Frame,使用反射时,可以使用System.Diagnostics.StackTrace获得调用堆栈(除此之外,由于JIT优化,调用堆栈可能是粗略的近似值),并检查包含的StackFrame对象 如何获取对堆栈帧中的方法正在其上执行的对象(this指针)的引用 我知道我可以通过调用stack frame对象上的GetMethod()来获得MethodBase,但我要寻找的是与GetObject()类似的东西(如果方法是静态的,它自然会返回null)。似乎堆栈帧对象只能查询静态确定的信息,如方法信息、原始文
澄清一下:我想要调用方法的对象实例。例如:如果方法Foo()在调用堆栈的某个地方被调用到对象实例A上,并且它级联到我执行堆栈跟踪的方法,我希望从中获取对A的引用,从中我执行堆栈跟踪。(不是方法库的声明类型)我不确定我是否完全理解您想要什么,但是如果您想知道某个堆栈帧的方法声明的类型,我认为这段代码返回:
StackTrace trace = new StackTrace();
Type methodOwner = trace.GetFrame(0).GetMethod().DeclaringType;
当然,您需要传递感兴趣的帧的索引(我使用0作为示例)。我非常确定这是不可能的。原因如下:
this
”(C#)标识符实际上只是实例方法(第一个)的一个参数,因此实际上静态方法和实例方法之间没有区别,编译器会神奇地将正确的this
传递给实例方法,当然,这意味着您需要访问所有方法参数才能获得this
对象。(哪个StackFrame
不支持)unsafe
code获取指向实例方法的第一个参数的指针,然后将其强制转换为正确的类型,这是可能的,但我不知道如何做到这一点,只是一个想法
顺便说一句,您可以想象实例方法在编译后与C#3.0扩展方法类似,它们将
this
指针作为第一个参数。可以获取对thiscall
对象的引用,但不能仅使用.NET代码。必须包含本机代码。即使使用动态类和System.Relation.Emit命名空间,NET也没有工具来访问另一个方法计算堆栈和参数
另一方面,若你们反汇编你们的.NET方法,你们可以看到这个引用根本并没有传递到物理堆栈上此调用
引用存储在ECX
(RCX
用于x64)寄存器中。所以,可以在堆栈上从您的方法爬升到要从中获取thiscall
对象的方法。然后在该方法的机器代码中查找将寄存器ECX(RCX)保存在堆栈中的指令,并从该引用所在的指令相对地址获取
当然,攀爬的方法在x32和x64应用中有很大的不同。要生成这样的函数,您不仅必须使用C#,还必须使用汇编代码,并记住x64下不允许使用内联汇编程序;它必须是一个完整的汇编模块。我想他指的是实例,而不是类型。是的,“object”指的是类型的实例;)是的,我意识到(你的问题其实很清楚;我想我有点累了…)太棒了!在我的例子中,我只需要类型。我知道调用方会将this指针传递给调用堆栈上被调用的方法,这就是为什么不存在的GetObject()会返回null(如果它是静态方法)以及实例方法中规范“this”指针的副本。但是,我同意你的#1论点,除了通过设计要求适当的权限很容易限制对对象的访问。真正的问题是StackFrame只是关于代码的一些元数据,而不是代码的实时版本。正如我所担心的那样。但我希望还有其他的课程可以利用。