- 论坛徽章:
- 5
|
本帖最后由 pacman2000 于 2015-06-07 22:43 编辑
*用户空间USER SPACE的使用
用户空间USER SPACE,是AS400所提供进程间通讯的另一个机制,可以保存一块较大的持久化数据。常用的三大机制,DATA AREA在核心系统中用于控制参数的设置,例如批处理平台并发数控制,联机平台各种标志,以及全局内容在*LDA的跨PGM保存传递。DATA QUEUE可用于进程间传递消息数据,因核心系统设计上处理进程的隔离性而没有用到。USER SPACE则用于实现输出报文的灵活性,保存核心系统交易处理过程中,可能产生返回的凭证打印报文接口段。
USER SPACE最大长度可达16M,必须命名以持久化。由于在系统中用于暂存一笔联机交易需要返回的附加报文数据,因此对持久化其实没有要求,但性能要求很高,又不能互相影响。于是将USER SPACE建立在QTEMP中。这样不同JOB各自有一份使用,而且QTEMP数据系统应该是在内存中建立的,恰好符合要求。
那么程序中如何访问呢,可以看实际使用的例子。
创建USER SPACE,名称为QTEMP/JOBADDUS。
- PGM PARM(&SPCLEN)
- INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
- DCL VAR(&PASSPCNM) TYPE(*CHAR) LEN(20)
- DCL VAR(&SPCATTR) TYPE(*CHAR) LEN(10)
- DCL VAR(&SPCLEN) TYPE(*UINT) LEN(4)
- DCL VAR(&SPCVALUE) TYPE(*CHAR) LEN(1)
- DCL VAR(&SPCAUTH) TYPE(*CHAR) LEN(10)
- DCL VAR(&SPCTEXT) TYPE(*CHAR) LEN(50)
- CHGVAR VAR(&PASSPCNM) VALUE('JOBADDUS QTEMP ')
- CHGVAR VAR(&SPCAUTH) VALUE('*CHANGE')
- CHGVAR VAR(&SPCTEXT) VALUE('附加报文用户空间')
- CHGVAR VAR(&SPCVALUE) VALUE(X'00')
- CALL PGM(QUSCRTUS) PARM(&PASSPCNM &SPCATTR +
- &SPCLEN &SPCVALUE &SPCAUTH &SPCTEXT)
- MONMSG MSGID(CPF9870)
- ENDPGM
复制代码 .
因为JOB结束时QTEMP自动释放,而JOB不结束的话USER SPACE可以重复使用,因此不需要人为去删除这个USER SPACE。
使用这个USER SPACE,会有两种情况。
一是交易运行过程中,产生需要附加的打印接口数据,这时候调用下面的程序记录进USER SPACE,注意,同时将已附加长度写进*LDA记录。另一种情况是组返回报文时,读取数据打包进报文,这个用的是后续的USER SPACE指针操作。
- #include <stdio.h>
- #include <string.h>
- #include <arpa/inet.h>
- #include "dscppgm/cpyrgt_h"
- #include "config_h"
- #include "msginfo_h"
- #include "opdtaac_h"
- extern void JOBUSPTR(char **usptr);
- extern void fill_str(char *buf, const char *str, int len);
- extern int get_output_arrays_count(oa_otct*);
- extern int set_otlen(int len);
- /* parm1 MESG
- parm2 ITNAME 10A
- parm3 ITCNT 2B hostorder
- parm4 ITPLEN 2B hostorder
- parm5 ITBUF ITCNT*ITPLEN
- */
- int main(int argc, char **argv)
- {
- oa_otct oa;
- rpg_msg_info *rpginfo;
- int olen, tlen;
- unsigned short pcnt, plen, tmp;
- char *obuf, *itbuf;
- char *itnm;
- char linebuf[LINENO_LEN+1];
- if (argc<2)
- return -1;
- rpginfo=(rpg_msg_info *)argv[1];
- if (argc!=6)
- {
- fill_str(rpginfo->msgflnm, __FILE__, FILENM_LEN);
- sprintf(linebuf, "%6d", __LINE__);
- fill_str(rpginfo->msgline, linebuf, LINENO_LEN);
- fill_str(rpginfo->msgid, "EPLMNOPCK ", MSG_ID_LEN);
- fill_str(rpginfo->msgtext, "组附加报文接口不正确", MSG_TEXT_LEN);
- fill_str(rpginfo->msgotds, "", MSG_TEXT_LEN);
- return -1;
- }
- itnm=argv[2];
- pcnt=*(unsigned short *)argv[3];
- plen=*(unsigned short *)argv[4];
- itbuf=argv[5];
- JOBUSPTR(&obuf);
- get_output_arrays_count(&oa);
- olen=oa.ot_len;
- obuf += olen;
- tlen = olen + ITNAME_SIZE + ITCNT_SIZE + ITPLEN_SIZE
- + (pcnt==0 ? plen : pcnt*plen);
- if (tlen > DAT_MAX_LEN)
- {
- char errbuf[MSG_TEXT_LEN];
- fill_str(rpginfo->msgflnm, __FILE__, FILENM_LEN);
- sprintf(linebuf, "%6d", __LINE__);
- fill_str(rpginfo->msgline, linebuf, LINENO_LEN);
- fill_str(rpginfo->msgid, "EPLMNOLEN ", MSG_ID_LEN);
- sprintf(errbuf, "组附加报文时长度%d + %d超过最大长度%d",
- olen, tlen-olen, DAT_MAX_LEN);
- fill_str(rpginfo->msgtext, errbuf, MSG_TEXT_LEN);
- fill_str(rpginfo->msgotds, "", MSG_TEXT_LEN);
- return -1;
- }
- fill_str(obuf, itnm, ITNAME_SIZE);
- obuf += ITNAME_SIZE;
- tmp = htons(pcnt);
- memcpy(obuf, &tmp, ITCNT_SIZE);
- obuf += ITCNT_SIZE;
- tmp = htons(plen);
- memcpy(obuf, &tmp, ITPLEN_SIZE);
- obuf += ITPLEN_SIZE;
- memcpy(obuf, itbuf, pcnt==0 ? plen : pcnt*plen);
- set_otlen(olen);
- return tlen;
- }
复制代码 .
这个程序将一个报文接口,以ITNAME接口名,ITCNT接口数组条数,ITLEN接口单条长度,ITBUF接口数据的方式,打包记录进USER SPACE。其中,JOBUSPTR用于获取USER SPACE的指针,然后就像普通内存一样操作。下面就是JOBUSPTR的程序。
- PGM PARM(&USPTR)
- INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
- DCL VAR(&PASSPCNM) TYPE(*CHAR) LEN(20)
- DCL VAR(&USPTR) TYPE(*PTR)
- CHGVAR VAR(&PASSPCNM) VALUE('JOBADDUS QTEMP ')
- CALL PGM(QUSPTRUS) PARM(&PASSPCNM &USPTR)
- ENDPGM
复制代码 .
核心系统中的用法到此为止。实际上,USER SPACE相关的命令和调用有不少,修改内容的方式除了获取指针,还可以用QUSRTVUS获取USER SPACE内容,QUSCHGUS修改USER SPACE内容。这两个调用以字符串的形式操作。遗憾的是,CL对USER SPACE的支持较少,需要用到的话自己写程序扩充吧。
|
|