在 RPGLE 程序中添加新的入口参数

Adding new entry parameter in an RPGLE program

我正在修改这个非常关键的 RPGLE 程序,其中的更改涉及向它添加一个新的入口参数。

*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        

程序入口参数列表如上,只是我现在添加的最后一个参数。该程序运行良好。但我有点担心的是,这是否会以某种方式影响调用该程序的其他区域。即未传递最后一个入口参数的调用程序。

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

If (%Addr(E_Grp) <> *NULL);            
  Chain (E_Grp:EWURS:ssmurs) MFMPP00;  
  If %Found();                         
    MchAllotted = *On;                 
    Leave;                             
  EndIf;                               
EndIf;                                 

代码中使用此参数的唯一其他区域如上所示。在这里,我确保在引用参数之前,检查参数是否已传递。

我已经测试过,效果很好。但是,考虑到应用的重要性,还是想到了寻求高手的帮助。

欢迎任何关于此的guidance/suggestions。

据我所知,RPG 将调用者的参数视为 "Do what you want"。这意味着如果 PGM01 被 PGM02 调用,其中 PGM1 接受 3 个参数,而 PGM2 调用带有 3 个参数,一切都很好。当 PGM01 想要 3 个参数而 PGM02 给了 2 个参数时,你可以这样做。但是你必须注意如果第三个参数是 *NULL(就像你所做的那样)会发生什么。如果您使用 4 个参数调用 PGM01,而 PGM01 仅 "wants" 3 个,则没有问题,因为 PGM01 不关心这些。

但我会保留 *ENTRY 样式,而是使用原型。在那里您可以定义如果参数是可省略的,则可以使用该参数但不是必须的。请阅读 D-SpecPR 关键字的手册。

您有内存损坏错误等待发生...

如果您尝试在没有最后一个参数的情况下调用该程序并且它似乎成功了,那么您只是幸运地没有使用内存区域......因此是零并且您的 %Addr(E_Grp) <> *NULL 按预期工作。

为了进行比较 %Addr(E_Grp) <> *NULL 您的调用程序必须为该参数传递 *OMIT 特殊值。显然,这需要更改所有调用程序。

你想要的是不必更改调用程序,因此你需要在被调用程序中将参数设置为 *NOPASS

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

然后在被调用的程序中,可以勾选

  1. 如果传递了参数
  2. 如果传递的参数为 NULL (*OMIT)

代码

// check if the parm was passed
if %parms() > = %parmnum(E_GRP);
  // check if passed parm is not NULL
  if  %Addr(E_Grp) <> *NULL;
     //ok to use E_Grp
     Chain (E_Grp:EWURS:ssmurs) MFMPP00;  
     If %Found();                         
       MchAllotted = *On;                 
       Leave;                             
     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;

您还可以将此技术与 更改的参数一起使用:

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;