关于函数调用得到传递参数的想法

(原创贴,转载请注名,谢谢 )
起源:
     近日来,一直致力于扩充公司的脚本解析引擎!脚本引擎的大致扩充功能如下:
     1、可在脚本中由用户自定义函数功能了,原来只有一个程序入口所有代码都在Begin..End之间写
      Begin
        //代码脚本
      end
      现在分成主脚本入口(既原Begin..End)与函数定义如
      function  GetMax(x,y: integer): integer;
      begin
        if x > y then
          result := x
        else
          result := y;
      end;
      begin
        MessageBox(GetMax(2,3));
      end;
      2、可支持在脚本中动态创建对象于对象之间传递引用
      原引擎只能固定的使用一些对象,其间不可赋值与引用如
      在Delphi中固定好一个对象 Button,则在脚本中使用就只能使用
      Button.Caption := 'sdf';
      而不支持 B := Button; 然后操作B;
      现在扩充如:
        MyBtn := TButton.Create(self);//支持了动态创建
        MyBtn.caption := 'test';
        MyBtn.parent := self;
        CBtn := MyBtn;//支持了引用
        MessageBox(CBtn.Caption);
      3、可支持在脚本中使用编译预处理指令了如
        {$I  MyFuncLib} //引用外部库,相当于Include
        {$IFDEF  gg}
        {$ELSEIFDEF  bb}
        {$ENDIF}
        {$IFNDEF cc}
        等编译预处理指令
       现在问题就出现于第四点的实现方式上了!
       那就是 动态的指定对象的事件了!
       此时,由于事件的类型有很多种!如果一个个的定义下来处理的话,实在太过繁琐!所以想到使用一个函数来实现
      调用所有对象事件的实现!而这些对象事件的的实现代码出现在脚本中,所以所有的事件执行都通过一个函数
      DoEvent来实现,该函数中只处理某对象事件属性对应的函数脚本。那么就需要传递触发该事件的时候传递到事件中的
      事件参数了!于是一个如何得到传递参数值的想法产生!

      实践!
         定义两个窗体,Form1,form2,在Form1中定义一个事件
         TTestEvent = procedure(Sender: TObject;x,y,z: integer) of object;
         property OnTest: TTestEvent read FonTest Write FOnTest;
         然后在窗体创建的时候设定OnTest属性的值!
         var
          Method: TMethod;
         begin
           MeThod.Data := Sender;
           Method.Code := @Test;
           SetMethodProp(self,'OnTest',Method)
         end;
         Test过程没有任何参数,此时的目的就是要在Test中得到由触发该事件的时候传递过来的各个参数的值!
         如
         procedure Test;
         begin
           //这里要求得到参数值!
         end;

         一段触发该事件的代码如下:
         Form1.OnTest(form1,1,2,3);
        打个断点。运行到这里的时候打开CPU窗口得到如下代码:
        {说明:对于一般的函数或过程,前三个参数分别放在 EAX、EDX、ECX,后面如果还有更多参数的话,就在堆栈
         里面;对于类的方法,EAX 固定用于存放类实例的地址,EDX、ECX 分别存放前两个参数,其余参数进栈。在堆
         栈中每个元素占用 4 Bytes,而前面说了,TVarRec 中储存的数据也是 4 Bytes,刚好一个参数在堆栈里面占
         一个位子,处理方便。另外,结果返回到 EAX 中。
         对于调用类的方法,其实有一个默认的隐藏参数 Self 作为第一个参数传入,放入EAX寄存器。
         因此我们看到的第一参数其实是第二个,因此我们处理的时候要注意。}
        Unit2.pas.36: Form1.OnTest(form1,1,2,3);
        00461481 6A02             push $02   //这里可知道是第三个参数压栈,2
        00461483 6A03             push $03   //第四个参数压栈,3
        00461485 8B1DA83C4600     mov

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值