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

How can I avoid unexpected procedure name conflicts in service programs?

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

刚才,我在 RPG ILE 程序中使用了 Throw 函数,该程序还静态调用了用于 IFS 文件系统上的流文件的 C 风格函数 access。该程序将不会编译并出现 "Definition supplied multiple times for symbol Throw" 的绑定错误。据我所知,使用 CRTBNDRPG 命令编译时无法获取绑定详细信息,但我能够注释掉我的 H DFTACTGRP(*NO) 规范,然后使用 CRTRPGMOD 后跟 CRTPGM 与附加参数 DETAIL(*EXTENDED)。这将打印出编译器在确定要静态绑定到哪些过程时查看的所有过程名称的详尽列表。这揭示了 "Throw" 的双重定义。在 72 页列表的深处,引用了 IBM 提供的服务程序 QJVAJNI(Java 本机接口),它包含一个导出过程,也名为 "Throw".

现在解决我眼前问题的最简单方法就是简单地重命名我的 "Throw" 过程,修改并重新编译我的服务程序,然后修改并重新编译所有引用它的程序。我可能会遵循该解决方案,但此行为引发了几个令人不安的问题:

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

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

  3. 如果以上两个问题都无能为力,是否意味着要保证绑定永远有效(尤其是"general purpose"错误处理等功能),一必须确保机器上任何地方 没有任何其他具有相同名称的导出过程?我不知道有什么设施可以缓解这个问题,比如名称空间。据我所知,ILE 编译器不使用其他平台在这种情况下可能使用的任何方法,例如重载或名称修改。像我在某些 C 导出(例如 _C_NEU_IFS_feof)上看到的那样开始 "informal namespacing" 以防止名称冲突是一个好习惯吗?或者,有没有办法在发布服务程序之前搜索机器上所有导出的程序以查找您想要的名称?

  4. IBM红皮书的作者都是ILE编程界的重量级人物。他们像我一样将他们推荐的导出之一命名为 "Throw"(尽管参数列表不同)。他们 运行 遇到过类似的问题吗?他们有不同的方法来解决名称冲突吗?

我发现可以为 CRTPGM 指定一个选项 *DUPPROC,但我不确定这是个好主意。文档说 "When multiple duplicate procedures are allowed, the first exported procedure in the list of specified modules and service programs that matches the import request is the procedure that is selected." 你能确定哪个符号将排在列表的第一位吗?顺序是否严格定义?

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

顺便说一句,developerworks 处有一个 RFE,用于将命名空间添加到 RPG。您需要登录 developerworks 才能使用 link,但您可以免费注册。然后访问RFE并为其投票。