DSP

call,callb,callp

2019-07-13 15:25发布

对于刚刚接触ILE模式开发的初级菜鸟而言,想要搞清楚这三者的区别还是有点难度的。网上虽然一些帖子对这三者进行了比较,但是这些帖子或是语焉不详,或是高度概括。对于老鸟来说或许已经足矣,但是对于初级菜鸟而言,还是理解起来并不容易。下面就由我这个中级菜鸟结合red book和自己的理解,从一个菜鸟的视角,来尽量的把这三者的区别描述清楚。 前提:你已对这三者有些初步的了解。  基本概念   1  CALL动态调用*PGM类型的OPM或者ILE 程序。(即可执行的程序,区别于*MODULE)。   2  CALLB静态调用module中的main procedurePEP)。(其实CALLB也可以调用subprocedure,但是不推荐这么用,好像也没人这么用。因为既然已经用定义原型的方式定义了subprocedure,为什么不使用CALLP呢?CALLPCALLB有更多优势)。 所以CALLB一般用来调用没有事先用原型定义声明的main procedure。(因为main procedure不需要定义原型也能用,subprocedure必须定义原型才能使用。如果mian procedure也定义原型了,那么也用CALLP吧)   3  CALLP 原型调用方式。顾名思义,使用CALLP必须要定义原型(prototyped),前两者则不用定义原型 CALLP既可以像CALL那样用动态方式调用OPM或者ILE程序,也可以像CALLB那样静态的调用procedureCALLP有很多优势,其中很重要的一点是他会在编译期提供参数检查(parameter checking),这样会避免一些运行期(run-time)的错误。    调用范围: CALL:OPM 或者ILE  program。(前提:调用的PGM要在当前LIB LIST中存在)  CALLB/CALLP: (前提:调用的procedure要在bind directory中有定义) 1同一个ILE program中的procedure2同一个ILEprogram中,相同的service program中的procedure 3同一个ILE program中,不同的service program中的procedure   如何选择三者?        CALLCALLB能实现的功能,CALLP都可以实现,并且CALLP还提供了参数检查,by value by read-only reference的传参方式等优势,并且定义个原型也并不是很困难的事,所以尽量使用CALLP   效率        这个地球人都知道,静态调用肯定比动态调用效率高,但是高多少,我没测试过,不清楚。   补充:什么是动态调用,静态调用,编译期参数检查? 假设:PGMA调用PGMB  动态调用:PGMA不知道PGMB在系统中的哪个位置,PGMA在调用PGMB的时候(run-time),按照当前的library list依次来寻找PGMB,这就是动态调用。   假设:PGM1 中的PROCA 调用PROCB 静态调用:PGM1 在编译的时候,编译器就把PROCB的地址信息保存在PGM1中了(具体binding的方式有by copy by reference两种)。当PROCA调用PROCB的时候,PROCA根据PROCB的地址,能够直接找到PROCB的位置,而不用像动态调用那样,要按照library list挨个library来搜索。这种方式就是静态调用。   编译期参数检查 Compile-time parameter checking是指在编译的时候,编译器会检查你传给procedure的参数是否和prototype里定义的一样。包括参数类型,以及是否有可忽略的参数等。不一样的话编译会报错,无法通过。能够减少运行期的错误。   假设PGMA 调用PGMBPGMB 2个入口参数,如下所示:                             *ENTRY PLIST                                           PARM      P1        5P 0                                               PARM      P2        5A 如果不用原型定义的话,那么PGMA调用PGMB的时候,传给PGMB2个参数,分别是10P 06A,即                                             CALL  PGMB                                           PARM              A1        10P 0                                           PARM              A2    6A 这样的话,PGMA是可以通过编译的,但是实际调用的时候,有可能造成数据异常,或者程序异常。 如果使用原型定义的话: D pgmbb        PR            EXTPGM(‘PGMB’) D                        5P 0 D                        5A 那么当PGMA再次传给PGMB  10P 0  10A的参数时,编译就会报错,无法通过, 减少运行期的错误。                                    CALLP  pgmbbA1,A2 /*编译无法通过  

热门文章