7

使用从著名的关于 RPG 异常和错误处理的 IBM 红皮书中学到的概念,我编写了一个服务程序QGPL/ERRFUNC来实现可重用的错误函数,如AssertThrowThrowMsgRethrowGetErrorMsg。我一直在几个不同的程序中使用它们,并且它们运行良好。

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

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

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

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

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

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

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

4

1 回答 1

8

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

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

于 2018-02-08T13:18:24.153 回答