Ibm midrange 在RPGLE程序中添加新的entry参数

Ibm midrange 在RPGLE程序中添加新的entry参数,ibm-midrange,rpgle,Ibm Midrange,Rpgle,我正在修改这个高度关键的RPGLE程序,其中的更改涉及向其添加一个新的entry参数 *entry plist parm ecorp corp parm edivi

我正在修改这个高度关键的RPGLE程序,其中的更改涉及向其添加一个新的entry参数

*entry        plist                                                              
              parm                    ecorp                          corp        
              parm                    edivi                          divi        
              parm                    eplvl                          parent lv   
              parm                    ewrsc                          wc rscd     
              parm                    eplnt                          plnt        
              parm                    eclvl                          child lv    
              parm                    emord                          ord         
              parm                    easst                          asst        
              parm                    emrwk                          mrwk#       
              parm                    eseqn                          seq #       
              parm                    easeq                          alt seq #   
              parm                    epprd                          alt seq #   
              parm                    eotst                          alt seq #   
              parm                    ewpqt                          alt seq #   
              parm                    ecmpc                          alt seq #   
              parm                    ewurs                          alt seq #   
              parm                    emurs                          alt seq #   
              parm                    epcdt                          alt seq #   
              parm                    E_Optn                         option          
              parm                    eeoj                           end of job      
              parm                    E_Pgm                          program         
              parm                    E_GRP                          MO GROUP        
程序输入参数列表如上所示,但我现在添加的最后一个参数除外。程序运行良好。但我有点担心的是,这是否会以某种方式影响到该项目的其他领域。i、 未传递最后一个entry参数的e Caller程序

这个新的输入参数将仅从作为更改一部分的另一个程序传递。有相当多的其他程序将调用传递与前面相同的参数列表的程序

If (%Addr(E_Grp) <> *NULL);            
  Chain (E_Grp:EWURS:ssmurs) MFMPP00;  
  If %Found();                         
    MchAllotted = *On;                 
    Leave;                             
  EndIf;                               
EndIf;                                 
If(%Addr(E_Grp)*NULL;
链(E_Grp:EWURS:ssmurs)MFMPP00;
如果%Found();
MchAllotted=*打开;
离开
EndIf;
EndIf;
代码中使用此参数的唯一其他区域如上所示。在这里,我确保在引用参数之前,检查参数是否已通过

我已经测试过了,效果很好。然而,考虑到应用程序的重要性,仍然认为需要寻求专家帮助


欢迎对此提供任何指导/建议。

据我所知,RPG正在考虑来自调用者的参数为“随心所欲”。这意味着如果PGM02调用PGM01,其中PGM1接受3个参数,PGM2使用3个参数调用,则一切正常。当PGM01需要3个参数而PGM02给出2个参数时,您可以这样做。但是,如果第三个参数是*NULL(就像您所做的那样),您必须注意会发生什么。如果使用4个参数调用PGM01,而PGM01只“想要”3个参数,则没有问题,因为PGM01并不关心这一点


但我会放弃*输入样式,而是使用原型。在这里,您可以定义,如果某个参数是可忽略的,那么该参数可以使用,但不必使用。请阅读
D-Spec
PR
关键字的手册。

据我所知,RPG将调用者的参数视为“随心所欲”。这意味着如果PGM02调用PGM01,其中PGM1接受3个参数,PGM2使用3个参数调用,则一切正常。当PGM01需要3个参数而PGM02给出2个参数时,您可以这样做。但是,如果第三个参数是*NULL(就像您所做的那样),您必须注意会发生什么。如果使用4个参数调用PGM01,而PGM01只“想要”3个参数,则没有问题,因为PGM01并不关心这一点


但我会放弃*输入样式,而是使用原型。在这里,您可以定义,如果某个参数是可忽略的,那么该参数可以使用,但不必使用。请阅读
D-Spec
PR
关键字的手册。

您的内存损坏错误正在等待发生

如果您尝试在没有最后一个参数的情况下调用该程序,并且该程序似乎正常工作,那么您就幸运地发现内存区域没有被使用……因此是零,并且您的
%Addr(E_Grp)*NULL
工作正常

为了进行比较,调用程序必须传递该参数的特殊值。显然,这需要更改所有调用程序

您想要的是不必更改调用程序,因此在被调用程序中需要的是参数
*NOPASS

您应该转换为调用的程序,以使用PR/PI而不是*条目PLIST。然后可以将最后一个参数标记为
options(*NOPASS*OMIT)

然后在调用的程序中,您可以检查

  • 如果参数被传递
  • 如果传递的parm为NULL(*省略)
  • 代码

    //检查parm是否通过
    如果%parms()>=%parmnum(E_GRP);
    //检查传递的parm是否不为空
    如果%Addr(E_Grp)*空;
    //可以使用E_Grp吗
    链(E_Grp:EWURS:ssmurs)MFMPP00;
    如果%Found();
    MchAllotted=*打开;
    离开
    endif;
    endif;
    endif;
    
    您有内存损坏错误等待发生

    如果您尝试在没有最后一个参数的情况下调用该程序,并且该程序似乎正常工作,那么您就幸运地发现内存区域没有被使用……因此是零,并且您的
    %Addr(E_Grp)*NULL
    工作正常

    为了进行比较,调用程序必须传递该参数的特殊值。显然,这需要更改所有调用程序

    您想要的是不必更改调用程序,因此在被调用程序中需要的是参数
    *NOPASS

    您应该转换为调用的程序,以使用PR/PI而不是*条目PLIST。然后可以将最后一个参数标记为
    options(*NOPASS*OMIT)

    然后在调用的程序中,您可以检查

  • 如果参数被传递
  • 如果传递的parm为NULL(*省略)
  • 代码

    //检查parm是否通过
    如果%parms()>=%parmnum(E_GRP);
    //检查传递的parm是否不为空
    如果%Addr(E_Grp)*空;
    //可以使用E_Grp吗
    链(E_Grp:EWURS:ssmurs)MFMPP00;
    如果%Found();
    MchAllotted=*打开;
    离开
    endif;
    endif;
    endif;
    
    如果该参数不在程序中修改,则更安全的使用方法是将一个变量初始化为默认值,如果传递了该参数,则将该参数复制到该变量。这样,如果添加了更多使用参数值的代码,他们就不必记得添加检查了

    ... Change the name of E_GRP parameter to E_GRP_parm
    
    dcl-s E_GRP ... INZ(whatever);
    
    if %parms() >= %parmnum(E_GRP_parm);
       E_GRP = E_GRP_parm;
    endif;
    
    您还可以将此技术与参数t一起使用
    ... Change the name of E_GRP parameter to E_GRP_parm
    
    dcl-s E_GRP ... INZ(whatever);
    
    if %parms() >= %parmnum(E_GRP_parm);
       E_GRP = E_GRP_parm;
    endif;
    
    dcl-pi *n;
       something_parm char(10) OPTIONS(*NOPASS);
    end-pi; 
    
    dcl-s something char(10) INZ('Whatever');
    
    // Get the value of the "someThing" parameter if it was passed
    if %parms() >= %parmnum(something_parm);
       someThing = someThing_parm;
    endif;
    ...
    // Update the "someThing" parameter if it was passed
    if %parms() >= %parmnum(someThing_parm);
       someThing_parm = someThing;
    endif;