PL / I程序中的z / OS MVS和z / OS UNIX Interop?

时间:2018-06-08 09:08:54

标签: unix mainframe zos mvs pl-i

我一直在寻找互联网上的各种资源,但无法找到我理解的明确答案,所以我在这里问:

如何从z / OS MVS调用z / OS UNIX代码?

我知道BPXBATCH PGM ...可以从z / OS MVS TSO调用z / OS UNIX程序。

但我可以这样做吗? G。在z / OS MVS PL / I程序中?

我想说的是,

  • 我可以静态链接z / OS MVS PL / I对象模块和z / OS UNIX C对象模块吗? (除了不同的编程语言之外,两者之间是否存在差异?)
  • 或者我可以动态链接两者吗?

我的用例是:我有一个20世纪70年代的旧PL / I库,现在需要进行网络连接。据我所知,在z / OS UNIX世界中,网络将顺利进行。

旧的PL / I库静态链接到我无法直接影响的多个其他软件。

P.S。:有声望更高的人可以建立一个stackoverflow PLI标签吗? ;-)

3 个答案:

答案 0 :(得分:5)

IBM语言环境(LE)运行时的一个目的是使COBOL,PL / I,汇编程序和FORTRAN可互操作。 C和C ++后来出现了。

生成非LE符合代码的编译器彼此之间没有很好的协作(如果你小心的话,你可以让所有的玩家一起工作)。生成LE符合代码的编译器确实可以很好地相互配合。我编写了使用C运行时例程(fopen,fseek,fread,fclose,各种正则表达式例程)的COBOL代码,并且由于LE而工作正常。

你的回应"嗯,有点"关于您是否使用IBM Enterprise PL / I 的问题可能表示您已经处于不受支持的配置中。

如果您的运行时是LE,那么您应该可以调用IBM提供的C运行时例程。如果您的运行时包含一些旧的不受支持的OS PL / I例程,那么可能能够调用IBM运行的C运行时例程 - 但是在那种情况下我就不会# 39;睡得很香。如果您可以重新链接旧代码以使用旧版OS PL / I运行时例程的LE版本,那么您可能会发现自己处于更加坚实的基础。

答案 1 :(得分:4)

对于z / OS和UNIX服务之间的关系存在很多困惑,但需要记住的是,这些并不是两个截然不同的事情......几乎任何任务都可以成为UNIX进程并通过正确的设置进行USS函数调用。

所以你的问题真的是两个问题:

  1. 如何将我的任务配置为UNIX进程,以便我可以发出USS内核函数?
  2. 我的PL / I编译器是否与LE运行时兼容,而对象库是否使用其他LE语言构建代码?
  3. 第一部分 - 如何将您的进程称为UNIX进程 - 非常简单。 IBM的方法要求您在调用UNIX函数之前连接到USS内核(OMVS地址空间),但通常这会在您第一次调用USS函数时自动发生。

    在使用USS之前,您确实需要一定的系统设置。当然,OMVS本身必须是活跃的(尽管这些日子并不罕见)。您的安全管理员需要为您提供UID号,并可能为您创建一个主目录。假设这部分没问题,您需要做的就是调用USS函数,现在您已成为UNIX服务进程。

    几乎任何应用程序都可以调用IBM的USS可调用服务(所有模块的名称都以BPX1 / BPX4开头) - 所需要的只是支持标准操作系统链接的东西。实际上,这几乎是IBM的运行时库所做的。一个很好的测试是调用BPX1GPI(即UNIX" getpid()")...它返回你的UNIX进程ID,如果你可以使这个工作,你就可以了很高兴与大多数其他UNIX服务一起使用。如果你要追踪LE" getpid()"实施,你发现它不仅仅是BPX1GPI上的薄层,所以没有理由你不能自己调用​​底层函数......这适用于大多数USS内核函数,不仅仅是getpid(),所以如果你不能弄清楚如何打开套接字,那么调用BPX1SOC总是一个好的计划B"。

    请记住,作为UNIX进程和在bash shell之类的东西之间运行会有区别...... shell会执行诸如设置STDIN / OUT / ERR之类的操作等等 - 如果你需要这些东西,如果你只是偶然连接到USS,你自己需要这样做。在设置标准文件描述符之前,您无法调用printf()之类的内容。

    一个简单的入门方法可能是为自己编写一个简短的C程序,该程序作为UNIX进程运行,设置STDIN / OUT / ERR(以及您需要的任何其他内容),然后调用当前的PL / I程序。这个"包装"您现有的代码可以设置您需要的任何USS项目,而无需在PL / I中执行任何操作。您可能还会发现这是一种方便的方法来做一些在PL / I中具有挑战性的事情,比如调用DLL函数......只需编写一个简短的C函数来执行您需要的操作,然后从PL /中调用此函数我代码。

    至于你问题的第二部分,如果你的PL / I使用LE运行时(除非它很老),那么混合来自其他库的代码要比听起来简单得多。至于核心运行时的东西,在大多数情况下,LE运行时功能足够聪明,可以是双模式的#34;从某种意义上说,相同的运行时功能在USS进程和非USS进程中都有效。对象代码是目标代码,并且(例如)打开的z / OS文件和打开的UNIX服务文件之间的区别仅仅是运行时调用SVC 19(对于z / OS OPEN)还是BPX1OPN(对于UNIX服务文件)。这只是意味着一旦您的代码被称为USS进程,您通常可以根据需要混合使用z / OS和USS函数。

    这也意味着你没有理由不能使用" libxyz.a"在PL / I程序中,假设LE级别没有不兼容性等等。让粘合剂以你期望的方式解决所有问题可能是一个挑战,但是如果你坚持下去它应该都有效。

    PL / I会有一些困难的事情(我道歉 - 我不是PL / I专家)。一个示例可能是调用libcurl示例,其中库是DLL而不是静态存档。同样,这里的诀窍可能是使用简短的C" stub"您可以从PL / I调用,并且该代码可以完成加载和调用DLL所需的魔法。否则,我认为一旦你将所有部分组合在一起,你会发现这是一个非常简单的练习。

答案 2 :(得分:2)

回答C和PL / I对象的静态链接'问题的一部分。

来自C或PL / I的编译对象只是编译对象。 编译它们的地方(TSO或USS)没有区别;以及它们所在的位置(PDS / PDSE或HFS目录)也没有区别。

实际上,您可以轻松地从HFS(例如,hello.o)复制到PDS。

cp hello.o "//'MYHLQ.OBJ(HELLO)'"

甚至在USS编译并将.o输出到PDS

c89 -c hello.c -o "//'MYHLQ.OBJ(HELLO)'"

然后使用BINDER链接(或反过来,将OBJECT从PDS复制到HFS,并使用ld链接)

但是,有两种目标文件格式,XOBJ和GOFF。

GOFF是较新的格式,如果您使用XPLINK,它是预先要求的格式。 z / OS上的64位LE程序也可以预先请求XPLINK。 GOFF本身也预先要求PDS / E.