如何避免服务程序中出现意外的程序名称冲突?

时间:2018-02-07 17:21:46

标签: ibm-midrange rpgle static-binding

使用从着名的IBM Red Paper on RPG Exception and Error Handling学到的概念,我编写了一个服务程序QGPL/ERRFUNC来实现可重复使用的错误函数,如AssertThrowThrowMsgRethrowGetErrorMsg。我一直在几个不同的程序中使用它们,并且它们一直运行良好。

刚才,我在RPG ILE程序中使用了Throw函数,该函数还静态调用与IFS文件系统上的流文件一起使用的C风格函数access。该程序将无法使用“为符号Throw多次提供定义”的绑定错误进行编译。据我所知,在使用CRTBNDRPG命令进行编译时,您无法获得绑定详细信息,但我能够注释掉我的H DFTACTGRP(*NO)规范,然后使用CRTRPGMOD编译它,然后{ {1}}附加参数CRTPGM。这将打印出一个广泛的列表,列出了编译器在确定静态绑定到哪些过程时所查看的所有过程名称。这揭示了“投掷”的双重定义。在72页面列表的深处,引用了IBM提供的服务程序DETAIL(*EXTENDED)(Java Native Interface),它包含一个名为“Throw”的导出过程。

现在最简单的解决方法是简单地重命名我的“Throw”程序,修改并重新编译我的服务程序,然后修改并重新编译引用它的所有程序。我可能会遵循这个解决方案,但这种行为引发了一些令人不安的问题:

  1. 为什么C风格的IFS功能会使用Java本机接口来完成其工作?我看到导入的服务程序如QJVAJNIQC2IFS在上下文中完全有意义。看起来IBM在这里引入了一个我们不得不忍受的意外依赖。我确信它是引用QC2POSIX的C服务程序之一,因为当我注释掉QJVAJNI函数调用时,access不会被引用。对QJVAJNI服务程序的引用可能是多层深度,这意味着导入导入。

  2. 为什么活页夹会通过服务程序导入进行彻底的递归?绑定器看起来像是通过每个服务程序使用的每个导入,无论该导入是否被程序和子程序绑定使用。这有必要吗?是否可以递归检查每个级别使用的导入?有没有办法改变这种行为?

  3. 如果对上述两个问题没有什么可以做的,这是否意味着要保证绑定始终有效(特别是对于“通用”函数,如错误处理),必须确保那里是不是任何其他导出程序机器上的任何地方具有相同的名称?我不知道任何像名称空间这样的设施可以缓解这个问题。据我所知,ILE编译器不使用其他平台在这种情况下可能使用的任何方法,如重载或名称修改。像我可以看到的一些C导出(例如QJVAJNI)以防止名称冲突一样,开始“非正式命名空间”是一个好习惯吗?或者,有没有办法在发布服务程序之前搜索机器上的所有导出过程以查找所需的名称?

  4. IBM红皮书的作者是ILE编程领域的一些重量级人物。他们像我一样命名了他们推荐的出口之一“投掷”(尽管有不同的参数列表)。他们遇到了类似的问题吗?他们有不同的方法来解决名称冲突吗?

  5. 我发现可以为_C_NEU_IFS_feof指定一个*DUPPROC选项,但我不确定这是个好主意。文档说“当允许多个重复过程时,与导入请求匹配的指定模块和服务程序列表中的第一个导出过程是所选的过程。”你能确定哪个符号将成为列表中的第一个吗?订单是否严格定义?

1 个答案:

答案 0 :(得分:8)

RPG中没有命名空间,或者就此而言没有C.绑定ILE程序时,绑定目录控制使用哪些服务程序(和模块)来解析名称。它不是系统上的每个服务程序。但是也有一些默认绑定的服务程序,如果使用由这些自动绑定的服务程序之一导出的名称,则会出现重复名称的问题。你是对的,*DUPPROC是个坏主意。处理在自动绑定服务程序中复制过程的名称的唯一方法是不使用这些名称定义新过程。有些人在命名他们的程序时使用伪命名空间技术,如serviceprogramname_procedurenameapplicationprefix_procedurename。其他人只是通过其他方式确保他们的程序具有唯一的名称。但是,在RPG支持某种形式的命名空间之前,您将不得不使用某种任意命名方案来确保过程名称的唯一性。

顺便说一句,developerworks有一个RFE可以为RPG添加名称空间。您需要登录developerworks才能获得工作链接,但您可以免费注册。然后访问RFE并投票支持。