免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 15879 | 回复: 22

闲谈call callb callp区别 [复制链接]

论坛徽章:
0
发表于 2011-06-28 16:01 |显示全部楼层
本帖最后由 niuhua77 于 2011-06-30 09:00 编辑

对于刚刚接触ILE模式开发的初级菜鸟而言,想要搞清楚这三者的区别还是有点难度的。网上虽然一些帖子对这三者进行了比较,但是这些帖子或是语焉不详,或是高度概括。对于老鸟来说或许已经足矣,但是对于初级菜鸟而言,还是理解起来并不容易。下面就由我这个中级菜鸟结合red book和自己的理解,从一个菜鸟的视角,来尽量的把这三者的区别描述清楚。
前提:你已对这三者有些初步的了解。
一 基本概念

1  CALL是用动态方式调用*PGM类型的OPM或者ILE 程序。(即可执行的程序,区别于*MODULE)。

2  CALLB是用静态方式调用module中的main procedure(PEP)。(其实CALLB也可以调用subprocedure,但是不推荐这么用,好像也没人这么用。因为既然已经用定义原型的方式定义了subprocedure,为什么不使用CALLP呢?CALLP比CALLB有更多优势)。
所以CALLB一般用来调用没有事先用原型定义声明的main procedure。(因为main procedure不需要定义原型也能用,subprocedure必须定义原型才能使用。如果mian procedure也定义原型了,那么也用CALLP吧)

3  CALLP 是原型调用方式。顾名思义,使用CALLP必须要定义原型(prototyped),前两者则不用定义原型 。CALLP既可以像CALL那样用动态方式调用OPM或者ILE程序,也可以像CALLB那样静态的调用procedure。CALLP有很多优势,其中很重要的一点是他会在编译期提供参数检查(parameter checking),这样会避免一些运行期(run-time)的错误。

二 调用范围:
        
     CALL——OPM 或者ILE  program。(前提:调用的PGM要在当前LIB LIST中存在)
     CALLB/CALLP EXTPROC—— (前提:调用的procedure要在bind directory中有定义)
            1同一个ILE program中的相同或不同的module中的procedure。
            2同一个ILEprogram中,相同的service program中的procedure
             3同一个ILE program中,不同的service program中的procedure。
      CALLP EXTPGM:OPM或者ILE program。(前提:调用的PGM要在当前LIB LIST中存在)——追加
三 如何选择三者?
        
CALL和CALLB能实现的功能,CALLP都可以实现,并且CALLP还提供了参数检查,by value ,by read-only reference的传参方式等优势,并且定义个原型也并不是很困难的事,所以尽量使用CALLP。

四 效率
        
这个地球人都知道,静态调用肯定比动态调用效率高,但是高多少,我没测试过,不清楚。

补充:什么是动态调用,静态调用,编译期参数检查?
1 假设:PGMA调用PGMB
动态调用:PGMA不知道PGMB在系统中的哪个位置,PGMA在调用PGMB的时候(run-time),按照当前的library list依次来寻找PGMB,这就是动态调用。

2 假设:PGM1 中的PROCA 调用PROCB
静态调用:PGM1 在编译的时候,编译器就把PROCB的地址信息保存在PGM1中了(具体binding的方式有by copy 和by reference两种)。当PROCA调用PROCB的时候,PROCA根据PROCB的地址,能够直接找到PROCB的位置,而不用像动态调用那样,要按照library list挨个library来搜索。这种方式就是静态调用。

3 编译期参数检查
Compile-time parameter checking是指在编译的时候,编译器会检查你传给procedure的参数是否和prototype里定义的一样。包括参数类型,以及是否有可忽略的参数等。不一样的话编译会报错,无法通过。能够减少运行期的错误。

假设PGMA 调用PGMB,PGMB 有2个入口参数,如下所示:
                                *ENTRY PLIST
                                                PARM      P1        5P 0        
                                                PARM      P2        5A
如果不用原型定义的话,那么PGMA调用PGMB的时候,传给PGMB2个参数,分别是10P 0和6A,即        
                                                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  pgmbb(A1:A2) /*编译无法通过——修正

论坛徽章:
0
发表于 2011-06-28 16:03 |显示全部楼层
写的比较通俗,凑合看吧

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-05 06:20:00
发表于 2011-06-28 20:49 |显示全部楼层
第一个顶一下,不错呀。。继续努力呀

论坛徽章:
0
发表于 2011-06-29 11:51 |显示全部楼层
本帖最后由 passthru 于 2011-06-29 11:57 编辑

明显的语法错误:CALLP  pgmb(A1,A2)

应该为:CALLP  pgmb(A1:A2)

论坛徽章:
0
发表于 2011-06-29 12:24 |显示全部楼层
本帖最后由 passthru 于 2011-06-29 12:28 编辑

-----------Crtpgm     Plist        Prototype         Bnddir             Libl
              (bndpgm)                (Nobndpgm)       
Callb        Yes        Yes         Yes          yes               No
Callp        Yes        Yes         Yes          Yes               Yes


callb不能调用libl下的外部pgm,这点是与callp最基本的差别。其它都一样。

论坛徽章:
0
发表于 2011-06-29 13:05 |显示全部楼层
回复 4# passthru


    这个错误是挺明显的,多谢指正

论坛徽章:
0
发表于 2011-06-29 13:13 |显示全部楼层
回复 5# passthru


    CALLB和CALLP都做静态调用的话,调用范围是没有区别。
    CALLP比CALLB多一个动态调用的功能,所以CALLP可以动态调用当前LIB LIST下的其他*PGM,而CALLB就不能了。

谢谢。

论坛徽章:
0
发表于 2011-06-29 13:58 |显示全部楼层
应该还要增加一种call的形式:无键字call,即function call。

在400下,call的形式有四种:
call
callb
callp
function call(无键字call)

论坛徽章:
0
发表于 2011-06-29 21:16 |显示全部楼层
如果细分的话,应该算是有5种吧
CALL
CALLB
CALLP EXTPROC
CALLP EXTPGM
EXPRESSION

论坛徽章:
0
发表于 2011-06-30 09:09 |显示全部楼层
本帖最后由 passthru 于 2011-06-30 09:46 编辑

补充一些内容点:

1)call、callb只能用在固定格式;callp则两个编程格式都可以使用。在自由格式下,只能用callp。

2)无键字call,即function call

如果,
c             callb    ‘MyProc’
c             parm                   Ptr

或 callp MyProc(Ptr);

用无键字call,即function call表示,则为,

    ReturnMsg = MyProc(Ptr);

无键字call,即function call,只有在Prototype原型定义,用procedure,直接export和return输出才能够实现。

    在编程实际应用过程中,用function call在subprocedures下不能处理F表(虽然实际上是可以处理,但是redbook上没有说明,且表示不能处理)。有时为了规范化编程,通常采用两级服务程序绑定,面向程序员用function call;而面向F表操作,用plist module。这两个服务程序可以装载到一个bnddir下,也可以放在不同的bnddir下。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP