如何在 ILE 和 PASE 之间相互调用

发布网友 发布时间:2022-04-19 10:03

我来回答

1个回答

热心网友 时间:2023-08-23 18:57

我们可以将 PASE 应用程序集成到已有的 ILE 系统中,这样用户就可以重用已有的 ILE 代码,使 PASE 应用获得在 ILE 系统中才有的特性。因为只有 ILE 才能充分发挥 IBM i 操作系统的独特优势。
我们可以通过以下几种方式在 ILE 端调用 PASE 应用程序:
在 ILE 绿屏命令行直接调用 PASE 端可执行应用程序
QSH CMD('pase_command parameters')
pase_command 为 PASE 端的可执行应用程序,它可以是该可执行应用程序的绝对路径,
也可以是当前 session 环境变量 PATH 下的可执行的应用程序。
清单 1. 使用 QSH CMD
QSH CMD('ps -ef')
QSH CMD('/QOpenSys/usr/bin/ls')

CALL QP2SHELL PARM('pase_command''parameters)
pase_command 为 PASE 端的可执行应用程序的绝对路径 , parameters 为该命令的命令行
参数。例如 :
清单 2. 在命令行使用 QP2SHELL
CALL QP2SHELL PARM('/QOpenSys/usr/bin/ls' '/QOpenSys/QIBM')

在 ILE 程序中调用 PASE 端应用程序
在 ILE 程序中调用 PASE 端可执行应用程序 , 我们可以使用以下三个 API 实现在 ILE 程序中调用 PASE 端应用程序。
QP2SHELL
QP2SHELL2
QP2SHELL 和 QP2SHELL2 这两个 API 提供了一个非常简单的使用 IBM i PASE 程序的
接口,直接使用要运行的 IBM i PASE 程序名字和输入参数作为 API 的输入,就可以调用 PASE 应用。
这两个 API 参数相同,差别在于 QP2SHELL()函数会创建新的激活组并在其中运行 PASE 程序。而 QP2SHELL2()函数会在调用者相同的激活组中运行 PASE 程序。这两个 API 都没有指示错误状态的返回值,也不会返回 PASE 程序的返回值。
程序示例:
清单 3. 在程序中使用 QP2SHELL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <qp2usr.h>
#include <qp2shell.h>

void main(int argc, char* argv[])
{
char* parm = “/”;
char* pasePgm = “/QOpenSys/bin/ls”;
QP2SHELL(pasePGM, parm);
}

Qp2RunPase
Qp2RunPase 允许用户提供更多的参数来对 PASE 程序的运行进行控制。它可以指定程
序名和运行参数,还可以定义 PASE 程序运行环境变量,以及 PASE 程序初始运行的 CCSID。Qp2RunPase 的返回值可以得到 PASE 程序执行的状态。PASE 程序结束返回时,导致 Qp2RunPase 返回并将控制权返还给 ILE 代码。下面是 Qp2RunPase 函数的原型:
清单 4. Qp2RunPase 函数声明
int Qp2RunPase(
const char* pathname,
const char* symbolName, const void* symbolData,
unsigned int symbolDataLen,
int ccsid,
const char* const* argv,
const char* const* envp);

参数说明:
pathName 输入参数:
表明 PASE 程序在 IFS 文件系统中的路径,可以使绝对路径,也可以是相对于作业当前路径的相对路径。
symbolName、symbolData、symbolDataLen 输入参数
symbolName 参数必须定义为为一个空指针; symbolData 和 symbolDataLen 参数通常被忽略。
CCSID 输入参数:
这个参数确定 PASE 程序初始运行的 CCSID。系统会将参数数据从作业默认的 CCSID 转换为对应的编码。例如,CCSID 设定为 1208,表明使用 UTF-8 编码。
argv 参数:
argv 指向一个指针数组,该指针数组为 IBM i PASE 程序的参数表。第一个参数是 PASE 程序的路径名,该参数的值与参数 pathName 的值相同。
envp 参数:
envp 参数指向一个指针数组,该指针数组用来定义 IBM i PASE 程序的环境变量。
Qp2RunPase 的返回值能够提供更多的信息,以便用户对 PASE 程序的运行状态进行处理。通常情况下,“0”表示正常返回,非零值表明错误返回,如“QP2RUNPASE_ERROR(-1)”或“QP2RUNPASE_RETURN_NOEXIT(-2)”这两个值表明函数本身的异常返回。IBM i 还提供了一些宏来处理返回值,如下表所示:
表 1. 使用宏处理 Qp2RunPase 返回值


含义

WIFEXITED(stat_val) 如果返回非零值,表明 Qp2RunPase 函数的执行过程有错误,需要调用下面的宏获得错误的细节信息
WEXITSTATUS(stat_val) 当宏 WIFEXITED(stat_val) 返回非零值时,表明执行过程有错误。该宏会返回 PASE 程序的返回值
WIFSIGNALED(stat_val) 检查 PASE 程序是否被 signal 异常终止
WTERMSIG(stat_val) 当宏 WIFSIGNALED(stat_val) 返回非零值时,表明执行过程被 signal 终止。这个宏确认具体收到的 signal number
程序示例:
清单 5. Qp2RunPase 函数使用实例
int rc = Qp2RunPase(“program/path/in/PASE”, NULL, NULL, 0, 819, (char**)&argv, NULL);
if (rc == QP2RUNPASE_ERROR || rc == QP2RUNPASE_RETURN_NOEXIT)
{
printf (“internal error”);
}
if (WIFEXITED(rc) != 0)
{
// Command exited normally, check its return code
paseRC = WEXITSTATUS(rc);
printf (“pase program exit with none zero return: %d”, paseRC);
}

在 ILE 程序中调用 PASE 函数
以上介绍了在 ILE 中调用 PASE 环境中的应用程序 IBM i 还提供了一组支持直接调用 PASE 共享库的 API。调用过程需要用到以下函数:
Qp2ptrsize: 获取 PASE 的指针长度。PASE 支持 32 位模式和 64 位模式。
Qp2dlopen: 类似于 UNIX 下的 dlopen() 函数,用于打开 PASE 共享库。
Qp2dlsym: 类似于 UNIX 下的 dlsym() 函数,用于查找对应的函数入口。
Qp2dlclose: 类似于 UNIX 下的 dlclose() 函数,用于关闭 PASE 共享库。
Qp2dlerror: 如果 Qp2dlopen、Qp2dlsym 或 Qp2dlclose 函数在执行过程出错,用户可以使用这个函数获取错误信息。
Qp2malloc: 在 PASE 中分配一块内存,共 ILE 与 PASE 之间进行数据交互。
Qp2free: 用于释放 Qp2mallloc 函数分配的内存。
Qp2CallPase
Qp2CallPase 使得用户可以在 ILE 程序中调用 PASE 共享库中的函数。Qp2CallPase 不会产生新的任务,只会在当前任务中执行 PASE 函数。
清单 6. Qp2CallPase 函数原型
#include <qp2user.h>

int Qp2CallPase(
const void* target,
const void* arglist,
const QP2_arg_type_t* signature,
QP2_result_type_t result_type,
void* result);

参数说明:
target
PASE 函数的描述符。
arglist:
IBM i PASE 函数的参数列表。
signature
参数的具体类型。QP2_ARG_END 表示 Signature 列表的结尾,QP2_ARG_WORD 表示 4-byte 数据,QP2_ARG_FLOAT32 表示 4-byte 浮点型数据,QP2_ARG_FLOAT64 表示 8-byte 浮点型数据。
result_type
调用的 PASE 函数的返回值的类型,在头文件 qp2user.h 中定义。QP2_RESULT_VOID 表明 PASE 函数没有返回值,QP2_RESULT_WORD 表示 4-byte 数据,QP2_RESULT_DWORD 表示 8-byte 数据,QP2_RESULT_FLOAT64 表示 8-byte 浮点型数据。
result
PASE 函数的返回值。
下面介绍 Qp2CallPase 函数的使用方法和步骤:
初始化:调用 IBM i PASE 环境之前必须对其进行初始化。IBM i PASE 环境提供了两个工具用来完成初始化,一个是 /usr/bin/start32,用来激活 32 位 IBM i PASE 环境,另一个是 /usr/bin/start64,用来激活 64 位 IBM i PASE 环境。每个 IBM i 进程必须且只能运行一个独立的 IBM iPASE 环境。
检查:调用 Qp2ptrsize() 来确定 IBM i PASE 环境是否正常运行。返回值:
0,表示没有完成初始化。
4,表示 PASE 环境运行在 32 位模式下
8,表示 PASE 环境运行在 64 位模式下。
加载库:用 Qp2dlopen 和 Qp2dlsym 将被调用的库加载至内存中,然后就可以定位被调用函数的入口。
调用 Qp2CallPase:使用 Qp2CallPase() API 激活 PASE 共享库函数,被调用的函数参数列表以指针数组的方式传递给 Qp2CallPase。ILE代码还需要提供一种方式来描述参数列表的类型,通常称为 Signature。用户可以在头文件 qsysinc/qp2usr.h 中找到这些类型定义。
终止 IBM i PASE 进程:需要先调用 Qp2dlclose() 来卸载 IBM i PASE 共享库,然后调用 Qp2EndPase() 函数来终止 start64 或 start32 程序启动的 PASE 环境。
清单 7. Qp2CallPase 函数使用实例
#include <stdio.h>
#include <qp2shell2.h>
#include <qp2user.h>
#define JOB_CCSID 0

int main(int argc, char* argv[])
{
QP2_ptr64_t id;
void* getpid_pase;
const QP2_arg_type_t signature[] = {QP2_ARG_END};
QP2_word_t result;
QP2SHELL2(“/usr/lib/start32”);
id = Qp2dlopen(NULL, QP2_RTLD_NOW, JOB_CCSID);
getpid_pase = Qp2dlsym(id, “getpid”, JOB_CCSID, NULL);

int rc = Qp2CallPase(getpid_pase,
NULL,// no argument list
signature,
QP2_RESULT_WORD,
&result)
printf (“IBM i PASE getpid() = &i\n”, result);
if (result == -1)
printf (“IBM i errno = %i\n”, *Qp2errnop());

Qp2dlclose(id);
Qp2EndPase();
return 0;
}

编译 ILE 端程序生成可执行的 PGM
在 ILE 端我们通常通过 CRTCMOD(如果源程序文件是由 ILE C 语言编写)或者 CRTCPPMOD(如果源程序文件是由 ILE C++ 语言编写)命令来将 ILE 端的程序编译成 MODULE,然后用 CRTPGM 来将编译好的 MODULE(s) 以及 Service Program 链接生成可执行的 PGM。
清单 8. 在 ILE 编译和链接程序
CRTCMOD MODULE(QYOURLIB/YOURMOD) SRCFILE(QYOURLIB/QCSRC)
或者:÷ CRTCPPMOD MODULE(QYOURLIB/YOURMOD)
SRCSTMF('/qopensys/myprogram/myprogram.cpp') INCDIR('/qopensys/myprogram/include')

CRTPGM PGM(QYOURLIB/YOURPGM) MODULE(QYOURLIB/YOURMOD)
BNDSVRPGM(QSYS/QP2USER)
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com