|
|
1
15
在我在Web上运行了很多次之后,答案是汇编程序在调用InternalSetDispatcher时假定存在堆栈帧。 似乎没有为调用InternalSetDispatcher生成堆栈帧。 因此,修复就如同使用$stack frames on compiler指令打开堆栈帧并重新构建一样简单。 感谢梅森帮助我回答这个问题。:) 编辑2012-0808 :如果您希望使用它,则可能希望在 Delphi Sping Framework . 我还没有测试过它,但是看起来它比这个代码更好地处理不同的调用约定。 编辑: 根据要求,我对艾伦密码的解释如下。除了需要打开堆栈帧,我还需要 在项目级别启用优化 要使其发挥作用:
|
|
|
2
6
从博客帖子:
代码正在消除InternalAdd的堆栈帧,它只有一个参数,
编辑: 作为对评论的回应,有一点你不知道。当你写“我知道代码在做什么(从父调用中清除堆栈帧)”时,你错了。 它不接触父呼叫。 它不是从“添加”中清除堆栈帧,而是从 现在的 调用,内部添加。
这里有一些基本的OO理论,因为你在这一点上似乎有点困惑,我承认这有点困惑。添加不
真的?
有一个参数,setEventDispatcher没有两个。它们实际上分别有两个和三个。未声明的任何方法调用的第一个参数
静止的
是
艾伦的代码所做的工作就是绕过编译器的限制。每个事件都是一个方法指针,但是对于泛型没有“方法约束”,因此编译器不知道T总是一个可以强制转换为t method的8字节记录。(事实上,这不一定是。你可以创建一个
所以当你看到
如果它要编译,那么它所做的相当于以下内容:
您的InternalSetDispatcher将要执行完全相同的操作:去掉它自己的一个参数调用,然后跳转到与调用方法setEventDispatcher具有完全相同参数列表的setDispatcher。不管调用函数有什么参数,或者它跳到的函数。有什么关系(这很关键!)setEventDispatcher和setDispatcher具有相同的调用签名。 所以,是的,您发布的假设代码可以正常工作,并且不会损坏调用堆栈。 |