Technical Blog Post
Abstract
如何通过User Space调用IBM i List API
Body
文本介绍了IBM i List API 的概念,并阐述了User Space与List API的关系及注意事项。举例说明如何通过User Space获取List API返回的内容。
1. User Space简介
User Space是类型为*USRSPC的IBM i对象,可以存储任何用户自定义数据。User Space是位于系统域或用户域的持久化对象。具有以下三个特点:
- 可以自动扩展
- 能在job或系统之间共享数据
- User Space及其数据在系统IPL(Initial Program Load)后依然存在
用户可以通过QDEVELOP/CRTUSRSPC USRSPC(<User Space Name>) 命令或Create User Space (QUSCRTUS) API创建User Space,User Space的预定义大小为16MB。需要注意的是,如果用户拥有对User Space的*CHANGE权限,当List API返回的数据量超过User Space预定义的大小时,List API能够自动增大User Space的容量。 否则,User Space中的数据将不全,List API将返回一个类似于CPF3CAA 的authority error错误信息。
IBM i 系统上所有List API 均具有统一的数据结构,方便开发人员使用(参见参考文献List API 数据结构)。List API数据结构中包含输入参数、头,和List输入部分。
IBM i提供了以下命令或API操作User Space:
- 创建User Space
API“QUSCRTUS”或命令“CRTUSRSPC”用于创建一个User Space
- 删除User Space
API“QUSDLTUS”或命令“DLTUSRSPC”用于删除一个User Space
- 读取User Space中的数据
API“QUSRTVUS”可以读取User Space中的数据
- 更改User Space中的数据
API“QUSCHGUS”能够改变User Space中的数据
2. List API简介
应用程序通常可以通过调用List API来获取IBM i上某种对象的集合。例如,使用QpzListPtfGroups API 能够返回IBM i 系统上的PTF组的集合;QSYLSTVC API能够返回系统上认证list上证书的集合。如果用户向IBM i系统请求两个或多于两个的对象时,可以考虑使用User Space,这样List API返回的数据便可以存储在User Space中。除了List API返回的数据以外,User Space中还含有一些元信息告诉用户如何读取其中的数据,这些元信息包括:
- 数据起点
- 数据元素个数
- 每个数据元素的长度
当然,在调用List API之前,需要准备好API需要的各种参数,也要指定用于存储返回数据的User Space的名字。每个API需要的参数格式不尽相同,详细情况请参考IBM Info Center。
通过程序读取User Space中的数据时,程序员可以根据编程语言是否支持指针而采取不同的读取方式。如果编程语言支持指针,可以直接将User Space的地址赋给一个指针读取或改变其中的内容;如果编程语言不支持指针,则可以利用API“QUSRTVUS”读取User Space中的内容。
3. 示例程序
下面我们通过清单1举例说明如何使用User Space获取List API QpzListPtfGroups返回的IBM i 系统上的PTF组的集合。
清单1使用User Space LSTPTFGRP存放QpzListPtfGroups API返回的内容,QTEMP为LSTPTFGRP所在的Library。程序首先删除同名的User Space并创建新的User Space,避免因API返回的数据被写入到一个存在数据的User Space中引起数据混乱;然后调用QpzListPtfGroups API,将数据存入User Space;最后读取User Space中的数据。
QpzListPtfGroups API的输入参数包括User Space名、数据返回的格式代码和PTF Group名的字符集代码,error_code存放错误信息。读取User Space时轮询每个Entry的信息,并在读取结束后删除该User Space,避免改User Space被其他程序使用导致的数据混乱。运行该程序,终端将打印出该IBM i上所有的PTF Group。QpzListPtfGroups API的详细介绍参见IBM I Info Center QpzListPtfGroups的介绍。
清单1. 在程序中使用User Space获取List API返回的内容
1 #include <stdio.h>
2 #include <qusec.h> /*error code结构 */
3 #include <qusgen.h> /*User Space 相关头文件 */
4 #include <quscrtus.h> /*使用QUSCRTUS API创建User Space */
5 #include <qusdltus.h>
6 #include <qusptrus.h>
7 #include <qpzgroup.h> /* PTF Group 头文件 */
8 #define USRSPC_PTFGRP "LSTPTFGRP QTEMP " /* User Space名 */
9 /* User Space 描述*/
10 #define USRSPC_PTFGRP_DESC "User space for QpzListPtfGroups "
11 int main(int argc, char* argv[])
12 {
13 Qus_Generic_Header_0100_t* header; /* 指向User Space header的指针*/
14 Qpz_LSTG0100_t* listdata; /* 指向User Space数据部分的指针 */
15 Qus_EC_t error_code; /* 错误代码 */
16 int i;
17 error_code.Bytes_Provided = sizeof(Qus_EC_t);
18 QUSDLTUS(USRSPC_PTFGRP,&error_code); /* 删除同名的User Space,避免数据混乱*/
19 error_code.Bytes_Provided = sizeof(Qus_EC_t);
20 QUSCRTUS(USRSPC_PTFGRP, " ", 10240, " ","*ALL ",
21 USRSPC_PTFGRP_DESC, "*YES ", &error_code); /* 创建一个新的User Space */
22 if(error_code.Bytes_Available)
23 {
24 printf("QUSCRTUS error: Exception_Id:[%s]\n",
25 error_code.Exception_Id);
26 return;
27 }
28 error_code.Bytes_Provided = sizeof(Qus_EC_t);
29 //调用系统API QpzListPtfGroups,列出系统上PTF组的集合
30 QpzListPtfGroups(USRSPC_PTFGRP, "LSTG0100", 37, &error_code);
31 if(error_code.Bytes_Available) /* 调用QpzListPtfGroups失败,处理错误信息 */
32 {
33 printf("QpzListPtfGroups error: Exception_Id:[%s]\n",
34 error_code.Exception_Id);
35 return;
36 }
37 error_code.Bytes_Provided = sizeof(Qus_EC_t);
38 QUSPTRUS(USRSPC_PTFGRP, &header, &error_code); /* 获得User Space的指针 */
39 if(error_code.Bytes_Available) /* 调用QUSPTRUS失败,处理错误信息 */
40 {
41 printf("QUSPTRUS error: Exception_Id:[%s]\n",
42 error_code.Exception_Id);
43 return;
44 }
45 /* 读取User Space中的信息 */
46 listdata = (Qpz_LSTG0100_t*)(((char*)header) + header->Offset_List_Data);
47 for(i = 0; i < header->Number_List_Entries; i++) /* 轮询每个Entry */
48 {
49 printf("listdata[%d]:[%s][%d][%d]\n", i, listdata[i].Name, listdata[i].Level,
50 listdata[i].Status);
51 }
52 error_code.Bytes_Provided = sizeof(Qus_EC_t);
53 QUSDLTUS(USRSPC_PTFGRP,&error_code); /* 删除该User Space */
54 }
在代码清单1中,第13行至第28行是为了调用QpzListPtfGroups API准备各个参数,包括准备错误信息存放位置,创建User Space等。其中第20行和第21行创建User Space,用于存放QpzListPtfGroups API返回的内容。
需要注意的是:List API 本身并不返回数据,只返回list包含对象的个数,真正的对象信息被存储到User Space中。因此,用户在调用List API之前需要预先创建一个User Space,并在调用List API时指定该User Space。List API返回的每条数据长度都相等,该长度需要从User Space中获得。
第30行调用QpzListPtfGroups API。代码第38行使用QUSPTRUS API获取读User Space的指针,准备读取QpzListPtfGroups API。代码第46行至第51行一次轮询List API返回到User Space中的每条记录,并打印输出记录内容。最后,代码第53行删除该User Space。
以上介绍了IBM I List API和User Space的概念,以及二者的关系。并通过一段C语言程序举例说明IBM I List API的用法。除C语言外,IBM i List API还支持其他语言的调用,包括Java等。IBM i 信息中心举例说明了以下四种语言的用法:
- OPM RPG
- ILE CL
- ILE RPG
- ILE COBOL
参考文献
作者:张荣荣、王胜军
了解更多关于IBM i 的信息,请关注IBM i 新浪官方微博@IBMiChina
UID
ibm11144732