动态调用内部过程

Rad*_*tor 0 rpgle ibm-midrange

有人可以解释我为什么不能使用%paddr()BIF 将内部过程的地址(存储在字符串变量中)分配给ProcPointer 吗?

我的想法是创建一个以数字为键的关联数组,以某个子过程的名称为值的关联数组。当用户在DSPF中输入数字2时,程序必须调用具有键“ 2”的过程。

据我了解,BIF %paddr()使用硬编码的过程名称或包含过程名称的字符串。但是,当给一个字符串变量时,编译器会抱怨的参数%PADDR无效。

jma*_*phy 5

这是因为过程是由编译器静态绑定的。因此,编译器需要在编译时知道要调用什么程序。但是,有些API可在运行时用于绑定服务程序。艾伦·坎平(Alan Campin)在这里有一些例子。

让我们再谈谈绑定。调用程序和过程时,IBM i提供两种不同类型的绑定。对于程序,绑定发生在第一次调用给定程序的运行时,它被解析并绑定到调用者。程序名称可以保留在变量中,并且由于该程序是在运行时绑定的,因此首次通过变量调用该程序时,它将被解析并绑定到调用方,此后,当变量中的值更改时,该程序在下一次调用时再次解析。这称为动态绑定。绑定发生在运行时,可能在每次调用程序时发生,并且在调用者或激活组结束时,绑定会丢失。

过程在编译期间是静态绑定的。过程或过程指针没有内置的运行时绑定。您可以使用过程指针来近似动态绑定,但是内部将过程绑定到过程指针,并且如果您通过%paddr()为过程指针提供地址,则绑定将在该点发生。甚至使用回调的API都是静态绑定的。API绑定到过程指针,调用者将过程指针绑定到回调过程本身,然后将绑定传递给API。在运行时没有解决方案发生。您可以使用此简单程序进行测试。

**free
ctl-opt dftactgrp(*no) actgrp(*new) BndDir('mybnddir');

dcl-s procPtr       Pointer(*proc);

dcl-pr proc         ExtProc(procPtr);
end-pr;

procPtr = %paddr('MissingProcedure');
proc();
return;
Run Code Online (Sandbox Code Playgroud)

该程序无法编译。在绑定步骤中失败,因为找不到MissingProcedure。期望接收回调作为参数的API,即使不知道回调是什么或回调是否存在也能够编译,因为它仅绑定到程序内部已经存在的过程指针本身。

因此,RPG不提供在运行时(动态)绑定过程的任何功能,但是IBM i确实提供了系统API,我们可以使用它们来手动解析服务程序中的过程。这就是我上面提到的Alan Campin的例子。因此,从技术上讲,是的,我们可以动态绑定到服务程序中的过程,但是RPG不提供这样做的便利。那只发生在编译时。