zoukankan      html  css  js  c++  java
  • call callb callp区别

      对于刚刚接触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中的procedure

    2同一个ILEprogram中,相同的service program中的procedure

    3同一个ILE program中,不同的service program中的procedure

    三、如何选择三者?   

      CALLCALLB能实现的功能,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 调用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 /*编译无法通过  

    原文链接:http://blog.chinaunix.net/uid-22547705-id-2125159.html

  • 相关阅读:
    互联网人25岁毕业 拿一万块钱月薪 (转)
    在windows平台编译openAL Android 库
    lua简单包装
    libevent 简单学习
    cocos2dx中使用tolua++使lua调用c++函数
    《OpenGL超级宝典》编程环境配置
    快速排序、归并排序、堆排序三种算法性能比较
    二叉树的三种遍历的递归与非递归算法
    boost之bind
    boost之内存管理
  • 原文地址:https://www.cnblogs.com/followyourdream/p/3286605.html
Copyright © 2011-2022 走看看